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 verar­beitete 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 Verar­beitung 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 mit­tels 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 Dokumen­treihenfolge 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 Nodese­quenz wird zunächst mit xsl:sort sortiert. Die Sortieranweisung ordnet die Knoten nach dem Zahlenwert ihres Attributs ersch-jahr, welches das Erschei­nungsjahr 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> ausge­geben 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 wer­den 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 ausge­geben wird. Interessant ist es in diesem Zusammenhang, den Wechsel des Cur­rent 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