xsl:for-each
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 6.)
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
Die Instruktion xsl:for-each bildet eine Schleife über alle Items einer mittels ihres select-Attributs zusammengestellten Sequenz und wendet auf diese jeweils den in der Instruktion enthaltenen Anweisungsblock an.
Klassifizierung | Instruktion |
Funktionsgruppe | Schleife über Eingabesequenz |
Einführung | XSLT 1.0 |
Position im Stylesheet und erlaubte Inhalte:
Das Element xsl:for-each darf überall in Template-Regeln, also innerhalb von xsl:template-Elementen, verwendet werden. Mehrere xsl:for-each-Anweisungen können dabei auch verschachtelt werden.
Ein xsl:for-each-Element darf eine beliebige Anzahl (auch keine) von xsl:sort-Instruktionen enthalten, die dann aber zu Beginn des enthaltenen Templateblockes stehen müssen. Anschließend dürfen, in beliebiger Folge und Anzahl, XSLT-Instruktionen, Literal Result Elements und Text auftreten.
Attribute:
Es gelten die Standardattribute. Ansonsten besitzt die Instruktion xsl:for-each ein einziges eigenes, obligatorisch zu verwendendes select-Attribut.
select
Wert | xpath-expression |
Verwendung | Obligatorisch |
Einführung | XSLT 1.0 |
Das select-Attribut enthält einen XPath-Ausdruck, dessen Auswertung eine Sequenz beliebiger Items ergibt, die als input sequence bezeichnet wird. Diese Sequenz muss nicht ausschließlich aus Knoten bestehen. Im Zuge der Verarbeitung gilt die Sequenz als aktuelle Sequenz (current sequence), jedes ihrer aktuell verarbeiteten Items dementsprechend als »Current Item«.
Hinweis: In XSLT 1.0 ist es dagegen ein Nodeset, der durch die Instruktion sukzessive abgearbeitet wird. Dieser Nodeset wird zur »Current Node List«, jeder jeweils verarbeitete Knoten zum »Current Node«.
Verwendungszweck:
xsl:for-each zählt zu jenen Anweisungen, die für die sogenannte »Pull-Verarbeitung« verwendet werden, die sich also die von ihr zu verarbeitenden Knoten aktiv selbst zusammenstellt. Dies geschieht mittels eines XPath-Ausdrucks im select-Attribut der Anweisung.
Die so zusammengestellte Sequenz wird in Eingabereihenfolge abgearbeitet, sofern keine Sortieranweisungen xsl:sort vorliegt. Ist dies der Fall, so wird die Sequenz zunächst sortiert und anschließend in der durch die Sortierung vorgegebene Reihenfolge abgearbeitet. Dabei wird für jedes Item jeweils der in xsl:for-each enthaltene Templateblock instanziiert. Im Moment der Verarbeitung erhält daher jedes der in der Liste enthaltenen Items den Fokus und wird zum »Current Item« (in XSLT 1.0: »Current Node«).
Die Stellung des gerade verarbeiteten Items in der Sequenz kann jederzeit mittels der Funktion fn:position() festgestellt werden, die Anzahl der Items in der Sequenz durch die Funktion fn:last().
Hinweis – Keine Aktivierung weiterer Template-Regeln in xsl:for-each:
Da xsl:for-each seine eigene Sequenz zusammenstellt und die aktuelle Template-Regel auf »null« setzt, ist aus dem Inneren der Instruktion keine Aktivierung von Template-Regeln mittels xsl:apply-imports oder xsl:next-match möglich.
Beispiele:
Beispiel 1 – Schleife über Elemente:
<xsl:for-each select="buchhandel/buch">
<p><xsl:value-of select="."/></p>
</xsl:for-each>
Es wird eine Schleife über alle Elemente <buch> gebildet, die Kindknoten eines Elements <buchhandel> sind. Die gefundenen Elemente werden in Dokumentreihenfolge ausgegeben.
Beispiel 2 – Schleife über sortierte Elemente:
<xsl:for-each select="buchhandel/buch">
<xsl:sort select="@ersch-jahr" data-type="number"/>
<p><xsl:value-of select="."/></p>
</xsl:for-each>
Die durch das select-Attribut von xsl:for-each zusammengestellte Nodesequenz wird zunächst mit xsl:sort sortiert. Die Sortieranweisung ordnet die Knoten nach dem Zahlenwert ihres Attributs ersch-jahr, welches das Erscheinungsjahr jedes Buches enthält.
Beispiel 3 – Zwei verschachtelte Schleifen:
<xsl:template match="lied">
<h3><xsl:value-of select="titel"/></h3>
<!-- Künstler ausgeben, die den Song spielen -->
<p><b>Künstler: </b><br/>
<!-- äußere Schleife -->
<xsl:for-each select="kuenstler">
<xsl:value-of select="."/>
<!-- Liste der Songs desselben Künstlers -->
(auch:
<!-- innere Schleife -->
<xsl:for-each select="//lied[kuenstler/text()=current()/text()][. != current()/parent::lied]">
<xsl:value-of select="titel"/>
<xsl:if test="fn:position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>)<br/>
</xsl:for-each>
</p>
</xsl:template>
Bei diesem etwas komplexeren Beispiel soll eine Liste von Songs <lied> ausgegeben werden und ihnen die Interpreten <kuenstler> zugeordnet werden. Zu den Interpreten soll jeweils eine Aufstellung der von ihnen ansonsten in der Liste enthaltenen Songs beigefügt werden.
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 ausgegeben:
<xsl:for-each select="//lied[kuenstler/text() = current()/text()][. != current()/parent::lied]">
Hierbei wird die Funktion current() verwendet, um sicherzustellen, dass der als erster Interpret ausgegebene Künstler nicht auch in der Kontextliste ausgegeben wird. Interessant ist es in diesem Zusammenhang, den Wechsel des Current Node zu betrachten.
Für das Template selbst ist auf Grund des match-Attributs ein <lied>-Knoten das Current Item. Von diesem ausgehend bildet die äußere xsl:for-each-Schleife eine Nodesequenz aller <kuenstler>-Elemente, die als Interpreten des Lieds gelistet sind. Aktueller Knoten ist innerhalb der Schleife der jeweils ausgegebene Künstler.
Die innere xsl:for-each-Schleife stellt eine neue Nodesequenz zusammen, die aus allen Songs des gerade ausgegebenen Künstlers besteht. Hier ist wichtig zu beachten, dass zum Zeitpunkt der Auswertung des select-Attributs der inneren Schleife noch der Current Node der äußeren(!) Schleife gilt – deshalb kann hier current() angewendet werden. Erst innerhalb des Schleifenblocks wechselt der aktuelle Knoten wieder zu einem <lied>-Knoten. Das Beispiel wird bei den Erklärungen zur Funktion current() genauer erläutert.
Elementdefinition:
XSLT 1.0:
<!-- Category: instruction -->
<xsl:for-each
select = node-set-expression>
<!-- Content: (xsl:sort*, template) -->
</xsl:for-each>
XSLT 2.0:
<!-- Category: instruction -->
<xsl:for-each
select = sequence-expression>
<!-- Content: (xsl:sort*, sequence-constructor) -->
</xsl:for-each>
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