current
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 5.)
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Kategorie: Kontextinformation innerhalb eines Nodesets
Herkunft: XSLT 1.0
Rückgabewert: Die current()-Funktion gibt eine Nodesequenz zurück, die aus einem einzelnen Knoten, dem Current Node, besteht.
Aufruf/Argumente:
current()
Keine Argumente
Verwendungszweck:
Mit dem Current Node, den die Funktion current() zurückliefert, ist der augenblicklich verarbeitete Knoten gemeint. Dieser entspricht in den meisten Fällen auch dem Kontextknoten, wie er auch über die XPath-Pattern "." oder "self::node()" zugänglich ist. Es ist also meist nicht notwendig, zwischen beiden zu unterscheiden, obwohl es sich streng genommen um verschiedene Konzepte handelt.
Unterschied zwischen XSLT 1.0 und XSLT 2.0
In XSLT 1.0 kann current() nicht in XPath-Pattern (beispielsweise im match-Attribut eines Templates) angewendet werden, da Pattern per Definition kontextfrei sein sollen – es würde sonst für den Mustervergleich einen Unterschied ergeben, welcher Knoten zum Zeitpunkt der Auswertung Current Node ist.
Genau dies ist in XSLT 2.0 anders: Die Funktion current() darf nunmehr innerhalb von XPath-Pattern verwendet werden und gibt in diesem Kontext den aktuell bei der Pattern-Auswertung getesteten Node zurück.
Im Inneren von Prädikaten (predicates) komplexerer XPath-Ausdrücke wechselt der Kontextknoten jedoch während der erfolgenden Prädikattests zum jeweils geprüften Knoten. Der Current Node als Bezugsknoten hingegen bleibt unverändert. Die Möglichkeit, im Zuge der Verarbeitung prüfen zu können, ob Kontextknoten und Current Node miteinander identisch sind oder gemeinsame Eigenschaften besitzen, kann daher wichtig sein. Ersteres, um zu erkennen, ob man nicht einen Knoten mit sich selbst vergleicht, Letzteres, um Bezüge zwischen dem Current Node und dem Kontextknoten herstellen zu können.
Die Funktion current(), die zuverlässig den Current Node zurückgibt, bietet in solchen Fällen die Möglichkeit, den Kontextknoten gegen diesen zu testen.
Ein anderer Fall, bei dem current() eingesetzt wird, sind verschachtelte Instruktionshierarchien. Hier kann es sich beispielsweise um ineinander geschachtelte xsl:for-each-Befehle handeln, wo der aktuell verarbeitete Knoten der äußeren Schleife den Bezugsknoten für ein Pattern der inneren Schleife bildet.
Beispiele:
Beispiel 1 – »Inner Join« in XSLT mit current():
Das Quelldokument:
Verwendet man Unterabfragen in XPath-Ausdrücken – vergleichbar mit »inner joins« bei SQL – so kann die Funktion current() verwendet werden, um kontextübergreifend Vergleiche vornehmen zu können. Bei einem XML-Dokument ähnlich diesem:
<?xml version="1.0" encoding="ISO-8859-1"?>
<lieblingslieder>
<lied>
<titel>The Last Time</titel>
<kuenstler>Rolling Stones</kuenstler>
<kuenstler>The Who</kuenstler>
</lied>
<lied>
<titel>I wanna be your man</titel>
<kuenstler>Beatles</kuenstler>
<kuenstler>Rolling Stones</kuenstler>
</lied>
...
</lieblingslieder>
Ein Lied kann dabei mehreren Künstlern zugeordnet werden, wie der Ausschnitt des XML-Dokuments zeigt. Hier soll eine Liste der Songs zusammen mit jeweils allen Interpreten ausgegeben werden. Hinter jedem Interpreten sollen zusätzlich dessen ebenfalls in der Liste befindlichen Songs aufgelistet werden, ohne dabei aber das gerade ausgegebene Lied zu wiederholen.
Das Stylesheet:
Hier das Template, das die einzelnen Lieder der Liste ausgibt:
<xsl:template match="lied">
<h3><xsl:value-of select="titel"/></h3>
<!-- kuenstler ausgeben, die den Song spielen -->
<p><b>Künstler: </b><br/><xsl:for-each select="kuenstler"><xsl:value-of select="."/><!-- Liste der Songs desselben Künstlers -->(auch: <xsl:for-each select="//lied[kuenstler/text()=current()/text()][. != current()/parent::lied]"><xsl:value-of select="titel"/><xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if></xsl:for-each>)<br/></xsl:for-each></p>
</xsl:template>
Das Ergebnis:
Ein Fragment des Ergebnisdokuments könnte wie folgt aussehen:
...
<h3>Lied: The Last Time</h3>
<p><b>Künstler: </b><br>Rolling Stones(auch: I wanna be your man, Satisfaction)<br>The Who(auch: My Generation)<br></p>
<h3>
...
Erklärung:
Die äußere xsl:for-each-Schleife gibt alle Künstler des aktuell im Template verarbeiteten Lieds aus:
<xsl:for-each select="kuenstler">
Die weiteren, im Kontext der ausgegebenen Künstler zu listenden, Songs werden in einer inneren xsl:for-each-Schleife verarbeitet:
<xsl:for-each select="//lied[kuenstler/text() = current()/text()][. != current()/parent::lied]">
Der hier relevante Teil ist der XPath-Ausdruck im select-Attribut der inneren xsl:for-each-Schleife. Hier werden zunächst pauschal alle <lied>-Elemente des Dokuments ausgewählt und mit Hilfe zweier Prädikate gefiltert. Für jedes Lied in Dokumentreihenfolge wird nun mit dem ersten Prädikat
[kuenstler/text() = current()/text()]
geprüft, ob es ein <kuenstler>-Element besitzt, dessen Textknoten (der Künstlername) dem des aktuellen Künstlernamens entspricht. Der Current Node current() ist das gerade ausgegebene Künstlerelement der äußeren xsl:for-each-Schleife, während die Künstlerelemente, mit denen verglichen wird (die Kontextknoten), diejenigen der gerade geprüften Lieder der inneren xsl:for-each-Schleife sind. Jetzt muss noch verhindert werden, dass in der Songliste zu den Künstlern auch der Titel des aktuell ausgegebenen Songs (der Current Node des Templates selbst) aufgeführt wird. Dies wird durch eine weitere Filterung mit dem zweiten Prädikat erreicht:
[. != current()/parent::lied]
Hier wird wieder vom aktuell ausgegebenen Künstlerelement current() ausgegangen und auf dessen Parentachse zum <lied>-Element zurückgegangen, das zuvor in der Hauptliste ausgegeben wurde. Dieses darf nun nicht identisch sein mit dem des gerade für die Kontextliste getesteten Lied. Sind es verschiedene Knoten, so wird das getestete Lied ausgegeben.
Funktionsdefinition:
XSLT 1.0:
current() => node set
XSLT 2.0:
current() as item()
Mögliche Kompatibilitätsprobleme XPath 2.0 zu XPath 1.0:
Als wichtigste Neuerung darf current() in XSLT 2.0 innerhalb von Pattern verwendet werden – der Ausdruck bezeichnet in diesem Fall den im Rahmen der Patternbewertung aktuell getesteten Node. Der Teil des Stylesheets, in dem sich das Pattern befindet, sollte sich daher nicht im abwärtskompatiblem Modus befinden. Der Rückgabewert ist unter XSLT 2.0 nicht als Nodeset (der aus einem Knoten, dem Current Node besteht) definiert, sondern zu Item verallgemeinert. Hieraus sollten sich keine Schwierigkeiten ergeben.
<< zurück | vor >> |
Tipp der data2type-Redaktion: Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an: |
Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.
Galileo Press, Rheinwerkallee 4, 53227 Bonn