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




java tutorial (3)

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

Я хотел проверить, работает ли мое преобразование нормально, поэтому вместо того, чтобы проверять его вручную, я написал еще один XSLT-код, который просто проверяет наличие этого конкретного тега в XML OUTPUT, если он является нулевым, то второй 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>

Он выводит все TEXT DATA, которые присутствуют в файле 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>

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


Answers

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

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

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


почему предыдущий код выводит TEXT, почему я должен настаивать на том, чтобы 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

Другой вариант попробовать - это простой

<img width="100" height="100" src="/root/Image/image.jpeg" class="CalloutRightPhoto"/>

т.е. без {}, но вместо этого давая прямой путь изображения





xslt