Ich liebe deine Frage. Sie sprechen sehr gut über das, was Sie noch nicht verstehen. Sie brauchen nur etwas, um die Dinge zusammenzubinden. Meine Empfehlung ist, dass Sie "Wie XSLT funktioniert" lesen , ein Kapitel, das ich geschrieben habe, um genau die Fragen zu beantworten, die Sie stellen. Ich würde gerne hören, ob es die Dinge für Sie zusammenhält.
Weniger formal werde ich versuchen, jede Ihrer Fragen zu beantworten.
- In welcher Reihenfolge werden die Vorlagen ausgeführt, und
- Stimmen sie bei der Ausführung mit (a) dem ursprünglichen Quell-XML oder (b) der aktuellen Ausgabe des XSLT bis zu diesem Punkt überein?
Zu jedem beliebigen Punkt in XSLT - Verarbeitung gibt es in gewissem Sinne, zwei Kontexten, die Sie identifizieren als (a) und (b): wo Sie in der sind Quellbaum , und wo Sie sind im Ergebnisbaum . Wo Sie sich im Quellbaum befinden, wird als aktueller Knoten bezeichnet . Es kann sich ändern und rund um den Quellbaum springen, wenn Sie beliebige Knotensätze auswählen, die mit XPath verarbeitet werden sollen. Konzeptionell "springen" Sie jedoch nie auf die gleiche Weise um den Ergebnisbaum herum. Der XSLT-Prozessor erstellt es ordnungsgemäß. Zuerst wird der Wurzelknoten des Ergebnisbaums erstellt. Anschließend werden untergeordnete Elemente hinzugefügt, und das Ergebnis wird in der Reihenfolge der Dokumente erstellt (Tiefe zuerst). [Ihr Beitrag motiviert mich, meine Software-Visualisierung für XSLT-Experimente wieder aufzunehmen ...]
Die Reihenfolge der Vorlagenregeln in einem Stylesheet spielt keine Rolle. Anhand des Stylesheets können Sie nicht erkennen, in welcher Reihenfolge die Vorlagenregeln instanziiert werden, wie oft eine Regel instanziiert wird oder ob sie überhaupt instanziiert wird. ( match="/"
ist eine Ausnahme; Sie können immer wissen, dass es ausgelöst wird.)
Ich gehe davon aus, dass Vorlage Nr. 1 zuerst ausgeführt wird. Ich weiß nicht, warum ich das annehme - liegt es nur daran, dass es zuerst im Dokument erscheint?
Nee. Es wird zuerst aufgerufen, selbst wenn Sie es zuletzt in das Dokument einfügen. Die Reihenfolge der Vorlagenregeln spielt keine Rolle (außer unter einer Fehlerbedingung, wenn mehr als eine Vorlagenregel mit derselben Priorität mit demselben Knoten übereinstimmt; selbst dann ist dies für den Implementierer optional und Sie sollten sich niemals auf ein solches Verhalten verlassen). Es wird zuerst aufgerufen, da das erste, was immer passiert, wenn Sie einen XSLT-Prozessor ausführen, ein virtueller Aufruf von ist <xsl:apply-templates select="/"/>
. Der eine virtuelle Aufruf erstellt den gesamten Ergebnisbaum. Draußen passiert nichts. Sie können das Verhalten dieser Anweisung anpassen oder "konfigurieren", indem Sie Vorlagenregeln definieren.
Wird Vorlage Nr. 2 ausgeführt? Es stimmt mit einem Knoten im Quell-XML überein, aber bis wir zu dieser Vorlage gelangen (vorausgesetzt, sie wird als zweite ausgeführt), befindet sich der Knoten "firstName" nicht im Ausgabebaum.
Vorlage Nr. 2 (oder andere Vorlagenregeln) werden niemals ausgelöst, es sei denn, Sie haben <xsl:apply-templates/>
irgendwo in der match="/"
Regel einen Aufruf . Wenn Sie keine haben, werden keine anderen Vorlagenregeln als match="/"
ausgelöst. Stellen Sie sich das so vor: Damit eine Vorlagenregel ausgelöst wird, kann sie nicht einfach mit einem Knoten in der Eingabe übereinstimmen. Es muss mit einem Knoten übereinstimmen, den Sie (mit ) verarbeiten möchten <xsl:apply-templates/>
. Umgekehrt stimmt es weiterhin so oft mit dem Knoten überein, wie Sie ihn verarbeiten möchten.
Würde [die match="/"
Vorlage] die Ausführung aller anderen Vorlagen verhindern, da nach Abschluss dieser ersten Vorlage nichts mehr übereinstimmt?
Diese Regel geht dem Rest durch nichts voraus <xsl:apply-templates/>
. Es gibt noch viele Knoten, die im Quellbaum verarbeitet werden könnten . Sie sind immer alle da, reif für die Ernte; Verarbeiten Sie jeden so oft, wie Sie möchten. Die einzige Möglichkeit, sie mithilfe von Vorlagenregeln zu verarbeiten, ist der Aufruf <xsl:apply-templates/>
.
Bis jetzt habe ich mich mit späteren Vorlagen befasst, die nicht ausgeführt werden, weil die Knoten, auf denen sie gearbeitet haben, nicht in der Ausgabe erscheinen, aber was ist mit der Umkehrung? Kann eine "frühere" Vorlage einen Knoten erstellen, mit dem eine "spätere" Vorlage etwas anfangen kann?
Es ist nicht so, dass eine "frühere" Vorlage einen neuen Knoten erstellt, der verarbeitet werden soll. Es ist so, dass eine "frühere" Vorlage wiederum mehr Knoten aus dem Quellbaum verarbeitet, wobei dieselbe Anweisung verwendet wird ( <xsl:apply-templates
). Sie können sich vorstellen, dass dieselbe "Funktion" rekursiv mit jeweils unterschiedlichen Parametern aufgerufen wird (die zu verarbeitenden Knoten werden durch den Kontext und das select
Attribut bestimmt).
Am Ende erhalten Sie einen baumstrukturierten Stapel rekursiver Aufrufe derselben "Funktion" ( <xsl:apply-templates>
). Und diese Baumstruktur ist isomorph zu Ihrem tatsächlichen Ergebnis. Nicht jeder merkt das oder hat so darüber nachgedacht; Das liegt daran, dass wir noch keine effektiven Visualisierungswerkzeuge haben.
Vorlage Nr. 1 erstellt einen neuen Knoten mit dem Namen "fullName". Vorlage Nr. 2 stimmt mit demselben Knoten überein. Wird Vorlage 2 ausgeführt, weil der Knoten "fullName" in der Ausgabe vorhanden ist, wenn wir zu Vorlage 2 gelangen?
Nee. Die einzige Möglichkeit, eine Verarbeitungskette zu erstellen, besteht darin, sie explizit auf diese Weise einzurichten. Erstellen Sie beispielsweise eine Variable, $tempTree
die das neue <fullName>
Element enthält , und verarbeiten Sie es dann wie folgt <xsl:apply-templates select="$tempTree">
. Um dies in XSLT 1.0 zu tun, müssen Sie die Variablenreferenz mit einer Erweiterungsfunktion (z. B. exsl:node-set()
) umschließen, aber in XSLT 2.0 funktioniert es so wie es ist.
Unabhängig davon, ob Sie Knoten aus dem ursprünglichen Quellbaum oder in einem von Ihnen erstellten temporären Baum verarbeiten, müssen Sie in beiden Fällen explizit angeben, welche Knoten Sie verarbeiten möchten.
Was wir nicht behandelt haben, ist, wie XSLT all sein implizites Verhalten erhält. Sie müssen auch die integrierten Vorlagenregeln verstehen . Ich schreibe ständig Stylesheets, die nicht einmal eine explizite Regel für den Stammknoten enthalten (match="/"
). Stattdessen verlasse ich mich auf die integrierte Regel für Stammknoten (Vorlagen auf untergeordnete Knoten anwenden), die mit der integrierten Regel für Elementknoten identisch ist. Auf diese Weise kann ich große Teile der Eingabe ignorieren, den XSLT-Prozessor automatisch durchlaufen lassen und nur dann etwas Besonderes tun, wenn er auf einen Knoten stößt, an dem ich interessiert bin. Oder ich könnte eine einzelne Regel schreiben, die alles rekursiv kopiert (Identitätsumwandlung genannt) und nur bei Bedarf überschreibt, um inkrementelle Änderungen an der Eingabe vorzunehmen. Nachdem Sie "Funktionsweise von XSLT" gelesen haben, müssen Sie als Nächstes die "Identitätstransformation" nachschlagen.
Mir ist klar, dass ich das "Zen" von XSLT zutiefst ignoriere. Bisher bestanden meine Stylesheets aus einer Vorlage, die mit dem Stammknoten übereinstimmt, und sind von dort aus vollständig prozedural. Ich bin es leid, das zu tun. Ich würde XSLT lieber richtig verstehen, daher meine Frage.
Ich applaudiere dir. Jetzt ist es Zeit, die "rote Pille" einzunehmen: Lesen Sie "Wie XSLT funktioniert"