Odpowiedzi:
<xsl:call-template>
jest bliskim odpowiednikiem wywołania funkcji w tradycyjnym języku programowania.
Możesz definiować funkcje w XSLT, takie jak ta prosta, która generuje ciąg.
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
Tę funkcję można wywołać za pomocą <xsl:call-template name="dosomething">
.
<xsl:apply-templates>
jest trochę inny iw tym tkwi prawdziwa moc XSLT: Pobiera dowolną liczbę węzłów XML (cokolwiek zdefiniujesz w select
atrybucie), iteruje je ( jest to ważne: szablony stosowania działają jak pętla! ) i znajduje pasujące szablony dla nich:
<!-- 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>
W ten sposób oddajesz trochę kontroli procesorowi XSLT - nie decydujesz, dokąd idzie przepływ programu, ale procesor robi to, znajdując najbardziej odpowiednie dopasowanie do węzła, który aktualnie przetwarza.
Jeśli do węzła można dopasować wiele szablonów, wygrywa ten z bardziej szczegółowym wyrażeniem dopasowania. Jeśli istnieje więcej niż jeden pasujący szablon o tej samej specyficzności, wygrywa ten zadeklarowany jako ostatni.
Możesz bardziej skoncentrować się na opracowywaniu szablonów i potrzebować mniej czasu na „hydraulikę”. Twoje programy staną się bardziej wydajne i zmodularyzowane, mniej zagnieżdżone i szybsze (ponieważ procesory XSLT są zoptymalizowane pod kątem dopasowywania szablonów).
Pojęciem, które należy zrozumieć w przypadku XSLT, jest „bieżący węzeł”. Z <xsl:apply-templates>
bieżącym węzłem przesuwa się z każdą iteracją, natomiast <xsl:call-template>
nie zmienia bieżącego węzła. To znaczy .
wewnątrz wywoływanego szablonu odnosi się do tego samego węzła, co .
w szablonie wywołującym. Nie dotyczy to szablonów aplikacji.
To podstawowa różnica. Istnieje kilka innych aspektów szablonów, które wpływają na ich zachowanie: swoje mode
i priority
fakt, że szablony mogą mieć zarówno name
a match
. Ma również wpływ na to, czy szablon został zaimportowany ( <xsl:import>
), czy nie. Są to zaawansowane zastosowania i możesz sobie z nimi poradzić, gdy tam dotrzesz.
<xsl:apply-templates>
zachowuje się jak pętla. Różnice implementacyjne po stronie procesora XSLT nie wpłyną na mnie jako programistę XSLT, wynik jest absolutnie taki sam dla implementacji równoległych i iteracyjnych. Ale nowicjuszowi XSLT z imperatywnym doświadczeniem pomaga wyobrazić sobie <xsl:apply-templates>
rodzaj pętli for-each, nawet jeśli - technicznie - tak nie jest.
Aby dodać do dobrej odpowiedzi @Tomalak:
Oto kilka niewymienionych i ważnych różnic :
xsl:apply-templates
jest znacznie bogatszy i głębszy niż, xsl:call-templates
a nawet z xsl:for-each
, po prostu dlatego, że nie wiemy, jaki kod zostanie zastosowany na węzłach selekcji - w ogólnym przypadku ten kod będzie inny dla różnych węzłów listy węzłów.
Kod, który zostanie zastosowany, może zostać napisany po napisaniu xsl:apply template
s i przez osoby, które nie znają oryginalnego autora.
Biblioteka FXSL „s implementacja funkcji wyższego rzędu (Hof) w XSLT nie byłoby możliwe, gdyby XSLT nie ma <xsl:apply-templates>
instrukcji.
Podsumowanie : Szablony i <xsl:apply-templates>
instrukcja pokazują, jak XSLT implementuje polimorfizm i radzi sobie z nim.
Źródła : Zobacz cały wątek: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templates
jest zwykle (ale niekoniecznie) używany do przetwarzania wszystkich lub podzbioru elementów podrzędnych bieżącego węzła ze wszystkimi odpowiednimi szablonami. Obsługuje to rekurencyjność aplikacji XSLT, która jest zgodna z (możliwą) rekurencyjnością przetworzonego XML.
xsl:call-template
z drugiej strony bardziej przypomina normalne wywołanie funkcji. Wykonujesz dokładnie jeden (nazwany) szablon, zwykle z co najmniej jednym parametrem.
Więc używam, xsl:apply-templates
jeśli chcę przechwycić przetwarzanie interesującego węzła i (zwykle) wstrzyknąć coś do strumienia wyjściowego. Typowy (uproszczony) przykład to
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
podczas gdy xsl:call-template
ja zazwyczaj rozwiązuję problemy, takie jak dodawanie tekstu niektórych podwęzłów do siebie, przekształcanie wybranych zestawów węzłów w tekst lub inne zestawy węzłów i tym podobne - wszystko, dla czego napisałbyś wyspecjalizowaną funkcję wielokrotnego użytku.
Jako dodatkowa uwaga do konkretnego tekstu pytania:
<xsl:call-template name="nodes"/>
Wywołuje to szablon o nazwie „węzły”:
<xsl:template name="nodes">...</xsl:template>
To jest inna semantyczna niż:
<xsl:apply-templates select="nodes"/>
... który stosuje wszystkie szablony do wszystkich elementów podrzędnych twojego obecnego węzła XML, którego nazwa to „węzły”.
Funkcjonalność jest rzeczywiście podobna (poza semantyką wywoływania, gdzie call-template
wymaga name
atrybutu i odpowiedniego szablonu nazw).
Jednak parser nie wykona tego samego sposobu.
Z MSDN :
W przeciwieństwie do
<xsl:apply-templates>
,<xsl:call-template>
nie zmienia bieżącego węzła ani bieżącej listy węzłów.
<xsl:apply-templates>
musi być implementowana jako pętla - wręcz przeciwnie, może być implementowana równolegle, ponieważ różne aplikacje na różnych węzłach listy węzłów są od siebie całkowicie niezależne.