Подтвердить что ты не робот

Как xsl: apply-templates соответствуют только тем шаблонам, которые я определил?

У меня есть несколько шаблонов, которые соответствуют различным узлам в XML-документе. Если я сделаю просто < XSL: Нанести-шаблоны/" >  он каким-то образом рекурсивно выводит текст всех узлов ниже. Я просто хочу, чтобы он рекурсивно соответствовал любому шаблону, который я определил. Как мне это сделать?

4b9b3361

Ответ 1

Это происходит из-за встроенные шаблоны в XSLT. XSLT имеет пару встроенных шаблонов, которые говорят:

  • когда вы применяете шаблоны к элементу, обрабатываете его дочерние элементы
  • когда вы применяете шаблоны к тексту node, укажите его значение

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

Прочтите полное объяснение здесь: http://www.dpawson.co.uk/xsl/sect2/defaultrule.html

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

<xsl:template match="text()" />

Ответ 2

Это, вероятно, самая частая проблема, которую испытывают даже опытные программисты XSLT.

Наблюдаемое поведение - именно то, как ведет себя XSLT-совместимый процессор shoud.

Учтите, что:

    <xsl:apply-templates/>

является аббревиатурой для:

    <xsl:apply-templates select="child::node()"/>

и существование правил встроенных шаблонов. Согласно XSLT 1.0 Spec.:

" 5.8 Встроенные правила шаблонов

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

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

Существует также встроенное правило шаблонов для каждого режима, что позволяет рекурсивной обработке продолжать в том же режиме в отсутствие успешного совпадения шаблонов с помощью явного правила шаблона в таблице стилей. Это правило шаблона применяется как к узлам элемента, так и к корню node. Ниже показано эквивалентное встроенное правило шаблона для режима 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()"/>

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

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

--- Конец спецификации спецификации XSLT ---

Итак, если автор хочет полностью контролировать обработку XSLT, они должны переопределить все встроенные шаблоны.

Например, если мы не хотим, чтобы text() узлы были скопированы на вывод, мы можем заставить их игнорировать, переопределив встроенный шаблон следующим образом:

    <xsl:template match="text()" />

Ответ 3

вы можете установить режим для применения только ваших собственных шаблонов:

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

<xsl:template match="somenode" mode="myMode">
  <!-- do something here -->
</xsl:template>

Другой вариант - перезаписать встроенные правила шаблонов (см., например, http://unix.com.ua/orelly/xml/xmlnut/ch08_07.htm)