Верно ли, что XSLT не будет обрабатывать дочерние узлы текущего узла, если apply-templates не называется явным объяснением? - PullRequest
1 голос
/ 10 октября 2009

Я думаю, что знаю ответ на этот вопрос, но мне просто нужно подтверждение, что я правильно понимаю.

Когда шаблон XSLT совпадает и выполняется, дочерние элементы текущего узла (текущий узел, на котором выполняется соответствующий шаблон) по умолчанию не обрабатываются. Вы должны вызвать "apply-templates", чтобы получить процессор для перехода в дочерние узлы текущего (совпавшего) узла.

Рассмотрим этот XML:

<person>
  <firstName>Deane</firstName>
  <lastName>Barker</lastName>
</person>

Во время преобразования процессор XSLT запускается с элемента person. Если он найдет шаблон для этого, он выполнит его, но затем не будет опускаться в элементы «firstName» и «lastName» для поиска шаблонов для них. Это будет сделано только в том случае, если «apply-templates» явно вызывается в шаблоне для «person».

Рассмотрим этот XSL:

<!-- Template #1 -->
<xsl:template match="person">
  I found a "person" element
</xsl:template>

<!-- Template #2 -->
<xsl:template match="firstName">
  I found a "firstName" element
</xsl:template>

В этом случае шаблон № 2 не будет запущен, верно? Обход XML-документа попадет в элемент person, найдет шаблон № 1, выполнит его, а затем никогда не попадет в дочерние элементы «person».

Если я поменяю первый шаблон на этот -

<!-- Template #1 -->
<xsl:template match="person">
  I found a "person" element
  <xsl:apply-templates select="firstName"/>
</xsl:template>

Только тогда запустится Шаблон №2. Я правильно понимаю?

Ответы [ 3 ]

4 голосов
/ 11 октября 2009

согласился на оба ответа; Ваша оценка того, что Шаблон №2 не будет обработан как таковая, абсолютно правильна.

Обратите внимание, что дочерние элементы узла (то есть его дочерние элементы, комментарии, текст и инструкции по обработке, но атрибуты , а не ) являются специальными только двумя способами:

  1. Значением по умолчанию атрибута select является "node()", XPath для выбора дочерних элементов и
  2. Встроенный шаблон правил для корневых узлов и узлов элементов предназначен для обработки дочерних элементов.

Кроме этих двух аспектов, дети не имеют особого статуса, когда дело доходит до выбора узлов для обработки. Вы можете выбрать любые узлы, которые вы хотите, включая предков. Вы можете пройтись по дереву в любом порядке. Экстремальный способ продемонстрировать это - написать таблицу стилей, которая переворачивает иерархию документа (переворачивает ее вверх дном). (Возможно, вы захотите использовать другой режим, чтобы при обработке родительских узлов вызывалось другое правило, чем при обработке дочерних узлов.)

Я также хочу проверить и убедиться, что вы понимаете различие между «корневым узлом» (переименованным в «узел документа» в XPath / XSLT 2.0) и корневым (или документом) элементом . В вашем примере XML, является , а не корневым узлом; это самый внешний элемент , который сам является дочерним элементом корневого узла, невидимым внешним контейнером в корне каждого дерева в модели данных XPath / XSLT.

Если вы хотите взять на себя управление обработкой справа от летучей мыши, вы всегда можете использовать или (при условии, что исходное дерево представляет собой правильно сформированный документ XML, а не фрагмент) . Это альтернативные способы сделать это. Одна из особенностей последнего заключается в том, что импортированный код, который содержит правило для match = "/", будет запускаться раньше, поскольку явные правила шаблона (даже если они имеют наименьший приоритет импорта) всегда имеют приоритет над встроенными правилами шаблона. Если у вас нет явного в импортируемой таблице стилей, то, пока вы не импортируете код, имеющий его, вы полагаетесь на встроенное правило шаблона для корневых узлов (применяйте шаблоны к дети - в этом случае примените шаблоны к элементу child).

Альтернативный способ взять контроль над битой, например, это использовать match = "/ person". Такое правило будет соответствовать любому элементу при условии, что он является дочерним для корневого узла. Если XML не имеет в качестве внешнего элемента, он не будет вызван. И если у вас также есть

2 голосов
/ 10 октября 2009

Да, это правильно. Вы должны явно вызвать apply-templates, чтобы пройти дальше вниз по дереву. Вы всегда можете использовать более общий <xsl:apply-templates /> (без @select) для применения шаблонов к каждому дочернему узлу (за исключением атрибутов этого элемента, которые должны быть явно выбраны с помощью select = "@ *").

Однако вы также можете использовать <xsl:copy-of select="person" />, который будет делать прямую копию любых выбранных элементов и всех их дочерних элементов и т. Д.

1 голос
/ 10 октября 2009

Да, вы правы. Как вы, возможно, уже знаете, это также зависит от того, как вы «входите» в логику apply-templates. В приведенном выше примере, если у вас не было шаблона для «лица», то правила шаблона по умолчанию были бы запущены (для всех дочерних узлов с точки, где вызывался apply-templates).

Но если какой-либо из шаблонов (которые соответствуют любым дочерним узлам в вызове apply-templates) был определен в вашей таблице стилей, применение шаблонов к дочерним узлам с этого узла и далее будет продиктовано шаблоном, вызывающим apply-templates, в противном случае они будет просто проигнорировано.

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