Каковы различия между 'call-template' и 'apply-templates' в XSL?

Я новичок в XSLT, поэтому я немного запутался в двух тегах,

<xsl:apply-templates name="nodes">

а также

<xsl:call-template select="nodes"> 

Так вы можете перечислить разницу между ними?

4 ответа

Решение

<xsl:call-template> является близким эквивалентом вызова функции на традиционном языке программирования.

Вы можете определять функции в XSLT, как этот простой, который выводит строку.

<xsl:template name="dosomething">
  <xsl:text>A function that does something</xsl:text>
</xsl:template>

Эта функция может быть вызвана через <xsl:call-template name="dosomething">,

<xsl:apply-templates> немного отличается, и в этом заключается реальная сила XSLT: он принимает любое количество узлов XML (все, что вы определяете в select атрибут), итерирует их (это важно: apply-templates работает как цикл!) и находит для них подходящие шаблоны:

<!-- sample XML snippet -->
<xml>
  <foo /><bar /><baz />
</xml>

<!-- sample XSLT snippet -->
<xsl:template match="xml">
  <xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>

<xsl:template match="foo"> <!-- will be called once -->
  <xsl:text>foo element encountered</xsl:text>
</xsl:template>

<xsl:template match="*"> <!-- will be called twice -->
  <xsl:text>other element countered</xsl:text>
</xsl:template>

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

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

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

Концепция, которую нужно понять с помощью XSLT, - это концепция "текущего узла". С <xsl:apply-templates> текущий узел движется с каждой итерацией, тогда как <xsl:call-template> не меняет текущий узел. То есть . в вызываемом шаблоне относится к тому же узлу, что и . в вызывающем шаблоне. Это не относится к apply-шаблонам.

Это основная разница. Есть некоторые другие аспекты шаблонов, которые влияют на их поведение: их mode а также priorityтот факт, что шаблоны могут иметь как name и match, Это также влияет на то, был ли шаблон импортирован (<xsl:import>) или нет. Это расширенные возможности, и вы можете справиться с ними, когда попадете туда.

Чтобы добавить к хорошему ответу @Tomalak:

Вот некоторые не упомянутые и важные отличия:

  1. xsl:apply-templates гораздо богаче и глубже xsl:call-templates и даже из xsl:for-each просто потому , что мы не знаем, какой код будет применен к узлам выбора - в общем случае этот код будет отличаться для разных узлов списка узлов.

  2. Код, который будет применен, может быть написан после xsl:apply template s был написан и людьми, которые не знают оригинального автора.

Реализация функций высшего порядка (HOF) в библиотеке FXSL в XSLT была бы невозможна, если бы в XSLT не было <xsl:apply-templates> инструкция.

Резюме: шаблоны и <xsl:apply-templates> Инструкция заключается в том, как XSLT реализует и имеет дело с полиморфизмом.

Ссылка: Смотрите всю эту ветку: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html

xsl:apply-templates обычно (но не обязательно) используется для обработки всех или подмножеств дочерних узлов текущего узла со всеми применимыми шаблонами. Это поддерживает рекурсивность приложения XSLT, которое соответствует (возможной) рекурсивности обработанного XML.

xsl:call-template с другой стороны, это больше похоже на обычный вызов функции. Вы выполняете ровно один (именованный) шаблон, обычно с одним или несколькими параметрами.

Поэтому я использую xsl:apply-templates если я хочу перехватить обработку интересного узла и (обычно) вставить что-то в выходной поток. Типичным (упрощенным) примером будет

<xsl:template match="foo">
  <bar>
    <xsl:apply-templates/>
  </bar>
</xsl:template>

тогда как с xsl:call-template Обычно я решаю такие проблемы, как сложение текста некоторых подузлов, преобразование выбранных наборов узлов в текстовые или другие наборы узлов и тому подобное - все, для чего вы бы написали специализированную многоразовую функцию.

Редактировать:

В качестве дополнительного замечания к вашему конкретному тексту вопроса:

<xsl:call-template name="nodes"/> 

Это вызывает шаблон, который называется "узлы":

    <xsl:template name="nodes">...</xsl:template>

Это другая семантика, чем:

<xsl:apply-templates select="nodes"/>

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

Функциональность действительно похожа (кроме вызывающей семантики, где call-template требует name атрибут и соответствующий шаблон имен).

Однако синтаксический анализатор не будет выполняться так же.

Из MSDN:

В отличие от <xsl:apply-templates>, <xsl:call-template> не изменяет текущий узел или текущий список узлов.

Другие вопросы по тегам