Почему XSLT выводит весь текст по умолчанию?


Привет я выполнил преобразование, которое отбрасывает тег, если он равен нулю.

Я хотел проверить, работает ли мое преобразование нормально, поэтому вместо того, чтобы проверять его вручную, я написал еще один XSLT-код, который просто проверяет наличие этого конкретного тега в выходном XML, если он равен null, то второй XSLT должен выводить текст "найдено". (На самом деле мне не нужен какой-то XML-вывод, но я просто использую XSLT для поиска.)

когда я пытался с этим кодом XSL ::

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
</xsl:stylesheet>

Он выводит все текстовые данные, которые присутствуют в XML-файле,

чтобы избежать этого, я должен был написать этот код::

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

почему прежний код выводит текст, Почему я должен настаивать на том, чтобы XSL игнорировал весь другой текст? это поведение всех синтаксических анализаторов XML или только моего собственного (я использую MSXML parser).

2 67

2 ответа:

почему прежний код выводит текст, почему я должен настаивать на том, чтобы XSL игнорировал все другое сообщение? это поведение все XML-Парсеры, или только моей собственной

вы обнаруживаете одну из самых фундаментальных функций XSLT, как указано в спецификации:встроенные шаблоны XSLT.

С спец:

есть встроенный шаблон правило разрешить продолжение рекурсивной обработки при отсутствии удачного паттерна сопоставление по явному шаблонному правилу в таблица стилей. Это правило шаблона применяется как к узлам элемента, так и к корневой узел. Ниже приведены эквивалент встроенного шаблона правило:

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

существует также встроенное правило шаблона для каждого режима, который позволяет рекурсивный обработка для продолжения в том же режим при отсутствии удачного соответствие шаблону по явный шаблон правило в таблице стилей. Этот шаблон правило применяется к обоим узлам элемента и корневой узел. Ниже приведены эквивалент встроенного шаблона правило для режима m.

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

существует также встроенное правило шаблона для текстовых и атрибутивных узлов, которые копирует текст через:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

встроенное правило шаблона для инструкции по обработке и комментарии - это ничего не делать.

<xsl:template match="processing-instruction()|comment()"/>

встроенный шаблонное правило для узлы пространства имен также ничего не делать. Нет шаблона, который может соответствовать узел пространства имен; Итак, встроенный правило шаблона является единственным шаблоном правило, которое применяется для пространства имен узлы.

встроенные правила шаблона рассматриваться как если бы они были ввезены неявно перед таблицей стилей и поэтому имеют более низкий приоритет импорта, чем все остальные правила шаблона. Таким образом, автор может переопределить встроенный правило шаблона путем включения явного правило шаблона.

таким образом, сообщенное поведение является результатом применения встроенных шаблонов-1-го и 2-го из всех трех из них.

это хороший шаблон дизайна XSLT для переопределения встроенных шаблонов С вашим собственным, который будет выдавать сообщение об ошибке при каждом вызове, так что программист сразу знает, что его преобразование "утечка":

, если есть этот XML документ:

<a>
  <b>
    <c>Don't want to see this</c>
  </b>
</a>

и оно обрабатывается с помощью этого преобразования:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="a|b">
   <xsl:copy>
      <xsl:attribute name="name">
        <xsl:value-of select="name()"/>
      </xsl:attribute>
      <xsl:apply-templates/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

результат:

<a name="a">
   <b name="b">Don't want to see this</b>
</a>

и программист будет очень смущен, как появился нежелательный текст.

однако, просто добавив Это catch-all template помогает избежать любой такой путаницы и немедленно поймать ошибки:

 <xsl:template match="*">
  <xsl:message terminate="no">
   WARNING: Unmatched element: <xsl:value-of select="name()"/>
  </xsl:message>

  <xsl:apply-templates/>
 </xsl:template>

теперь, кроме запутанного вывода программист получает предупреждение, которое объясняет проблему немедленно:

 WARNING: Unmatched element: c

есть несколько встроенные правила шаблона в XSL, один из которых является следующим:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

выводит текст.