Я новичок в XSLT, поэтому меня немного смущают два тега,
<xsl:apply-templates name="nodes">
и
<xsl:call-template select="nodes">
Можете ли вы перечислить разницу между ними?
источник
Я новичок в XSLT, поэтому меня немного смущают два тега,
<xsl:apply-templates name="nodes">
и
<xsl:call-template select="nodes">
Можете ли вы перечислить разницу между ними?
<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>
при этом текущий узел не изменяется. Т.е. .
внутри вызываемого шаблона относится к тому же узлу, что и .
в вызывающем шаблоне. Это не относится к шаблонам приложений.
Это основная разница. Есть и другие аспекты шаблонов, которые влияют на их поведение: их mode
и priority
, тот факт, что шаблоны могут иметь как a, так name
и match
. Это также влияет на то, был ли шаблон импортирован ( <xsl:import>
) или нет. Это сложные варианты использования, и вы сможете с ними справиться, когда доберетесь до них.
<xsl:apply-templates>
должна быть реализована как цикл - наоборот, он может быть реализован параллельно, потому что разные приложения на разных узлах списка узлов абсолютно независимы друг от друга.<xsl:apply-templates>
ведет себя как цикл. Различия в реализации на стороне XSLT-процессора не повлияют на меня как на XSLT-программиста, результат абсолютно одинаков как для параллельных, так и для итеративных реализаций. Но для новичка в XSLT с императивным фоном это помогает представить себе<xsl:apply-templates>
как бы своего рода цикл для каждого, даже если - технически - это не так.apply-templates
иcall-template
инструкции не для этого. Это механизм рекурсии в XSLT. И, как ответил Димитр, шаблоны приложений - это полиморфизм или механизм, управляемый данными.Чтобы добавить к хорошему ответу @Tomalak:
Вот некоторые не упомянутые и важные отличия :
xsl:apply-templates
намного богаче и глубже, чемxsl:call-templates
и даже отxsl:for-each
, просто потому , что мы не знаем, какой код будет применен к узлам выборки - в общем случае этот код будет отличаться для разных узлов списка узлов.Код, который будет применяться, может быть написан после того, как
xsl:apply template
был написан s, и людьми, которые не знают первоначального автора.Библиотека FXSL «s реализация функций высшего порядка (Хоф) в 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:call-template
я обычно решаю такие проблемы, как добавление текста некоторых подузлов вместе, преобразование выбранных наборов узлов в текст или другие наборы узлов и т.п. - все, для чего вы бы написали специализированную функцию многократного использования.Редактировать:
В качестве дополнительного примечания к тексту вашего конкретного вопроса:
Это вызывает шаблон с именем «узлы»:
Это другая семантика, чем:
... который применяет все шаблоны ко всем дочерним элементам вашего текущего узла XML, имя которого - «узлы».
источник
Функциональность действительно похожа (кроме семантики вызова, где
call-template
требуетсяname
атрибут и соответствующий шаблон имен).Однако парсер не будет работать таким же образом.
Из MSDN :
источник