Jakie są różnice między' call-template 'a' apply-template ' w XSL?

Jestem nowy w XSLT więc jestem trochę zdezorientowany co do dwóch tagów,

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

I

<xsl:call-template select="nodes"> 
Czy możesz wymienić różnicę między nimi?
Author: Tomalak, 2010-12-18

4 answers

<xsl:call-template> jest bliskim odpowiednikiem wywołania funkcji w tradycyjnym języku programowania.

Możesz zdefiniować funkcje w XSLT, jak ta prosta, która wyświetla ciąg znaków.

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

Funkcję tę można wywołać poprzez <xsl:call-template name="dosomething">.

<xsl:apply-templates> jest trochę inny i w nim jest prawdziwa moc XSLT: pobiera dowolną liczbę węzłów XML (cokolwiek zdefiniujesz w atrybucie select), iteruje je (to ważne: apply-templates działa jak pętla!) i znajduje pasujące do nich szablony:

<!-- 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 rezygnujesz z małej kontroli nad procesorem XSLT - nie ty decydujesz, gdzie przebiega przepływ programu, ale procesor znajduje Najbardziej odpowiednie dopasowanie do węzła, który obecnie przetwarza.

Jeśli wiele szablonów może dopasować węzeł, wygrywa ten z bardziej określonym wyrażeniem dopasowania. Jeśli istnieje więcej niż jeden pasujący szablon o tej samej specyficzności, wygrywa ten, który zadeklarował ostatni.

Możesz skoncentrować się bardziej na opracowywanie szablonów i potrzebują mniej czasu, aby zrobić "hydraulika". Twoje programy staną się bardziej wydajne i modularne, mniej zagnieżdżone i szybsze (ponieważ procesory XSLT są zoptymalizowane pod kątem dopasowywania szablonów).

W XSLT należy rozumieć pojęcie "bieżącego węzła". Z <xsl:apply-templates> bieżący węzeł porusza się z każdą iteracją, podczas gdy <xsl:call-template> nie zmienia bieżącego węzła. Np. . w wywołanym szablonie odnosi się do tego samego węzła co . w wywołującym szablonie. To Nie dotyczy apply-templates.

To jest podstawowa różnica. Istnieje kilka innych aspektów szablonów, które wpływają na ich zachowanie: ich mode i priority, fakt, że szablony mogą mieć zarówno name, jak i match. Ma to również wpływ na to, czy szablon został zaimportowany (<xsl:import>), czy też nie. Są to zaawansowane zastosowania i możesz sobie z nimi poradzić, gdy tam dotrzesz.
 171
Author: Tomalak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-14 22:00:37

Aby dodać do dobrej odpowiedzi przez @ Tomalak:

Oto kilka niezapowiedzianych i ważnych różnic:

  1. xsl:apply-templates jest znacznie bogatsza i głębsza niż xsl:call-templates, a nawet od xsl:for-each, po prostu dlatego, że nie wiemy jaki kod zostanie zastosowany na węzłach wybór -- w ogólnym przypadku kod ten będzie inny dla różne węzły listy węzłów.

  2. Kod, który zostanie zastosowany można pisać w sposób po xsl:apply template S był napisane i przez ludzie, którzy nie znają oryginalnego autora.

Biblioteka fxsl implementacja funkcji wyższego rzędu (HOF) w XSLT nie byłaby możliwa , gdyby XSLT nie posiadał instrukcji <xsl:apply-templates>.

Summary : Templates and the <xsl:apply-templates> instruction is how XSLT implements and deals with polymorphism.

Reference : Zobacz cały wątek: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html

 15
Author: Dimitre Novatchev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-19 17:09:27

xsl:apply-templates jest zwykle (ale niekoniecznie) używany do przetwarzania wszystkich lub podzbiorów Potomków bieżącego węzła z wszystkimi odpowiednimi szablonami. Obsługuje to rekurencyjność aplikacji XSLT, która odpowiada (możliwej) rekurencyjności przetwarzanego XML.

xsl:call-template z drugiej strony jest bardziej jak normalne wywołanie funkcji. Wykonujesz dokładnie jeden (nazwany) szablon, zwykle z jednym lub kilkoma parametrami.

Więc używam xsl:apply-templates Jeśli chcę przechwycić przetwarzanie interesujący węzeł i (zazwyczaj) wstrzyknąć coś do strumienia wyjściowego. Typowy (uproszczony) przykład to

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

Podczas gdy z xsl:call-template zazwyczaj rozwiązuję problemy, takie jak dodawanie tekstu niektórych podnodów razem, przekształcanie wybranych nodesetów w tekst lub inne nodesety i tym podobne-wszystko, do czego można napisać wyspecjalizowaną funkcję wielokrotnego użytku.

Edit:

Jako dodatkowa uwaga do Twojego tekstu pytania:

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

To wywołuje szablon, który nazwa "węzły":

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

Jest to inna semantyka niż:

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

...który stosuje wszystkie szablony do wszystkich dzieci bieżącego węzła XML, którego nazwa to "węzły".

 8
Author: TToni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-16 15:07:04

Funkcjonalność jest rzeczywiście podobna (poza semantyką wywołującą, gdzie call-template wymaga atrybutu name i odpowiedniego szablonu nazw).

Jednak parser nie będzie działał w ten sam sposób.

From MSDN :

<xsl:apply-templates>, <xsl:call-template> nie zmienia aktualnego węzła ani bieżącej listy węzłów.

 2
Author: Oded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-18 12:42:52