Antworten:
<xsl:call-template>
ist eine enge Entsprechung zum Aufrufen einer Funktion in einer traditionellen Programmiersprache.
Sie können Funktionen in XSLT definieren, wie diese einfache, die eine Zeichenfolge ausgibt.
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
Diese Funktion kann über aufgerufen werden <xsl:call-template name="dosomething">
.
<xsl:apply-templates>
ist ein wenig anders und darin liegt die wahre Stärke von XSLT: Es benötigt eine beliebige Anzahl von XML-Knoten (was auch immer Sie im select
Attribut definieren ), iteriert sie ( dies ist wichtig: apply-templates funktioniert wie eine Schleife! ) und findet passende Vorlagen für Sie:
<!-- 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>
Auf diese Weise geben Sie dem XSLT-Prozessor ein wenig Kontrolle - Sie entscheiden nicht, wohin der Programmablauf geht, sondern der Prozessor findet die am besten geeignete Übereinstimmung für den Knoten, den er gerade verarbeitet.
Wenn mehrere Vorlagen mit einem Knoten übereinstimmen können, gewinnt die mit dem spezifischeren Übereinstimmungsausdruck. Wenn mehr als eine übereinstimmende Vorlage mit derselben Spezifität vorhanden ist, gewinnt die zuletzt deklarierte.
Sie können sich mehr auf die Entwicklung von Vorlagen konzentrieren und benötigen weniger Zeit für die "Installation". Ihre Programme werden leistungsfähiger und modularer, weniger tief verschachtelt und schneller (da XSLT-Prozessoren für den Vorlagenabgleich optimiert sind).
Ein mit XSLT zu verstehendes Konzept ist das des "aktuellen Knotens". Mit <xsl:apply-templates>
dem aktuellen Knoten geht es mit jeder Iteration weiter, während <xsl:call-template>
sich der aktuelle Knoten nicht ändert. Das heißt, das .
innerhalb einer aufgerufenen Vorlage bezieht sich auf denselben Knoten wie das .
in der aufrufenden Vorlage. Dies ist bei Apply-Vorlagen nicht der Fall.
Das ist der grundlegende Unterschied. Es gibt einige andere Aspekte von Vorlagen, die sich auf ihr Verhalten auswirken: Ihre mode
und priority
die Tatsache, dass Vorlagen sowohl a name
als auch a haben können match
. Es hat auch Auswirkungen darauf, ob die Vorlage importiert wurde ( <xsl:import>
) oder nicht. Dies sind fortgeschrittene Verwendungszwecke, mit denen Sie sich befassen können, wenn Sie dort ankommen.
<xsl:apply-templates>
wie eine Schleife. Implementierungsunterschiede auf der Seite des XSLT-Prozessors wirken sich nicht auf mich als XSLT-Programmierer aus. Das Ergebnis ist für parallelisierte und iterative Implementierungen absolut gleich. Aber für einen XSLT-Neuling mit einem zwingenden Hintergrund ist es hilfreich, sich <xsl:apply-templates>
eine Art für jede Schleife vorzustellen , auch wenn dies technisch nicht der Fall ist.
Um die gute Antwort von @Tomalak zu ergänzen:
Hier sind einige nicht erwähnte und wichtige Unterschiede :
xsl:apply-templates
ist viel reicher und tiefer als xsl:call-templates
und sogar von xsl:for-each
, einfach weil wir nicht wissen, welcher Code auf die Knoten der Auswahl angewendet wird - im allgemeinen Fall ist dieser Code für verschiedene Knoten der Knotenliste unterschiedlich.
Der Code, der angewendet wird, kann weit nach dem Schreiben des xsl:apply template
s und von Personen geschrieben werden, die den ursprünglichen Autor nicht kennen.
Die Implementierung von Funktionen höherer Ordnung (HOF) durch die FXSL-Bibliothek in XSLT wäre nicht möglich, wenn XSLT die <xsl:apply-templates>
Anweisung nicht hätte .
Zusammenfassung : Vorlagen und die <xsl:apply-templates>
Anleitung zeigen, wie XSLT Polymorphismus implementiert und damit umgeht.
Referenz : Siehe den gesamten Thread: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templates
wird normalerweise (aber nicht unbedingt) verwendet, um alle oder eine Teilmenge von untergeordneten Elementen des aktuellen Knotens mit allen anwendbaren Vorlagen zu verarbeiten. Dies unterstützt die Rekursivität der XSLT-Anwendung, die der (möglichen) Rekursivität des verarbeiteten XML entspricht.
xsl:call-template
Auf der anderen Seite ähnelt es viel mehr einem normalen Funktionsaufruf. Sie führen genau eine (benannte) Vorlage aus, normalerweise mit einem oder mehreren Parametern.
Also benutze ich, xsl:apply-templates
wenn ich die Verarbeitung eines interessanten Knotens abfangen und (normalerweise) etwas in den Ausgabestream einfügen möchte. Ein typisches (vereinfachtes) Beispiel wäre
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
Während xsl:call-template
ich normalerweise Probleme wie das Hinzufügen des Textes einiger Unterknoten, das Umwandeln ausgewählter Knotensätze in Text oder andere Knotensätze und dergleichen löse, löse ich alles, wofür Sie eine spezielle, wiederverwendbare Funktion schreiben würden.
Als zusätzliche Bemerkung zu Ihrem spezifischen Fragetext:
<xsl:call-template name="nodes"/>
Dies ruft eine Vorlage mit dem Namen "Knoten" auf:
<xsl:template name="nodes">...</xsl:template>
Dies ist eine andere Semantik als:
<xsl:apply-templates select="nodes"/>
... wendet alle Vorlagen auf alle untergeordneten Elemente Ihres aktuellen XML-Knotens an, dessen Name "Knoten" lautet.
Die Funktionalität ist in der Tat ähnlich (abgesehen von der aufrufenden Semantik, für call-template
die ein name
Attribut und eine entsprechende Namensvorlage erforderlich sind ).
Der Parser wird jedoch nicht auf die gleiche Weise ausgeführt.
Von MSDN :
Im Gegensatz zu
<xsl:apply-templates>
,<xsl:call-template>
ändert nicht die aktuellen Knoten oder die aktuelle Knoten-Liste.
<xsl:apply-templates>
, die als Schleife implementiert werden müssen - im Gegenteil, sie kann parallel implementiert werden, da die verschiedenen Anwendungen auf den verschiedenen Knoten der Knotenliste absolut unabhängig voneinander sind.