Відповіді:
<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
і a match
. Це також впливає на те, чи імпортували шаблон ( <xsl:import>
) чи ні. Це розширені можливості використання, і ви можете боротися з ними, коли потрапите.
<xsl:apply-templates>
поводиться як цикл. Різниці в реалізації на кінці процесора XSLT не вплинуть на мене як на програміста XSLT, результат абсолютно однаковий для паралельних та ітеративних реалізацій. Але для новачків XSLT, які мають загальний досвід, це допомагає уявляти собі <xsl:apply-templates>
як певний цикл для кожного циклу, навіть якщо - технічно - це не так.
Щоб додати добру відповідь від @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: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, ім'я якого - "вузли".
<xsl:apply-templates>
повинна бути реалізована як цикл - навпаки, вона може бути реалізована паралельно, тому що різні програми на різних вузлах списку вузлів абсолютно незалежні один від одного.