Nummerierung sortierter Sequenzen
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 2.)
Ist eine Sequenz sortiert, so verliert sie den Bezug zur Dokumentreihenfolge, den sie ursprünglich gehabt haben mag. Sollen ihre Items nummeriert werden, so erfolgt dies am Einfachsten mit den Funktionen fn:position() und fn:last(), falls nicht eine indirekte Nummerierung per HTML möglich ist. Jedoch auch die Instruktion xsl:number bietet mit Hilfe ihres value-Attributs Möglichkeiten in Bezug auf sortierte Sequenzen.
Einfache Nummerierung mit fn:position()
Die Funktion fn:position() gibt bekanntlich die Kontextposition, also die Indexnummer eines Items in der aktuell verarbeiteten Sequenz aus. Sie kann somit auch zur Erzeugung einer einfachen Nummerierung eingesetzt werden.
Der folgende Beispielquelltext nummeriert eine sortierte Sequenz aller Elemente <datensatz> eines fiktiven Eingabedokuments. Die Funktion fn:last() gibt dabei die Anzahl der Elemente in der Sequenz aus (die der im Dokument entspricht), die Funktion fn:position() die Position des augenblicklich verarbeiteten <zeile>-Elements:
<xsl:apply-templates select="//datensatz">
<xsl:sort/>
</xsl:apply-templates>
<xsl:template match="datensatz">
<p>Zeile <xsl:value-of select="fn:position()"/> von <xsl:value-of select="fn:last()"/>: <xsl:value-of select="."/></p>
</xsl:template>
ergibt beispielsweise:
<p>Zeile 1 von 50: Sortierter Datensatz.</p>
<p>Zeile 2 von 50: Sortierter Datensatz.</p>
<p>Zeile 3 von 50: Sortierter Datensatz.</p>
<p>Zeile 4 von 50: Sortierter Datensatz.</p>
...
Der Vorteil dieser Methode ist, dass sie wunderbar einfach ist, der Nachteil wiederum, dass man nur mit den von fn:position() oder fn:last() zurückgegebenen Ganzzahlen arbeiten kann. Die vortrefflichen Formatierungsmöglichkeiten des Formatstrings von xsl:number stehen hier nicht zur Verfügung.
Nummerierung mit xsl:number und value-Attribut
Der eben erwähnte Umstand stellt kein tatsächliches Problem dar. In der Tat kann die Ausgabe von xsl:number ohne Schwierigkeiten von der Dokumentreihenfolge ab- und mittels fn:position() an eine Sequenzsortierung angekoppelt werden.
Hierzu dient das value-Attribut von xsl:number, das einen konkreten Zahlenwert entgegennimmt und so den Wert der vor das nummerierte Element gestellten Nummerierung bestimmt. Dieser Wert kann von fn:position() geliefert werden. Nun steht auch format zur Verfügung, um die Bezifferung nach Gusto durchzuführen.
Für folgendes Quelldokument:
...
<liste>
<listenelement>B Listenelement</listenelement>
<listenelement>C Listenelement</listenelement>
<listenelement>A Listenelement</listenelement>
</liste>
...
wird zunächst durch dieses Template eine nach Stringwert sortierte Sequenz aus <listenelement>-Knoten erzeugt:
<xsl:template match="liste">
<div>
<xsl:apply-templates>
<xsl:sort/>
</xsl:apply-templates>
</div>
</xsl:template>
Bei der anschließenden Verarbeitung in diesem Template kann die Nummerierung wegen der erfolgten Sortierung nicht mehr auf Grundlage der Dokumentreihenfolge vorgenommen werden. Hier muss die ermittelte Position in der aktuellen Sequenz in Verbindung mit dem value-Attribut verwendet werden:
<xsl:template match="listenelement">
<p><xsl:number value="fn:position()" format="i) " /><xsl:apply-templates/></p>
</xsl:template>
Hinweis:
Da der value sich aus dem XPath-Ausdruck ergibt, werden das count-, das level- und das from-Attribut in diesem Fall nicht benötigt. Sind sie dennoch vorhanden, so werden sie ignoriert.
Dies erzeugt folgende Ausgabe im Ergebnisdokument:
...
<div>
<p>i) A Listenelement</p>
<p>ii) B Listenelement</p>
<p>iii) C Listenelement</p>
</div>
...
Dahingegen hätte eine »normale« Nummerierung ohne die Verwendung von value="fn:position()" eine falsche Bezifferung aufgrund der realen Dokumentreihenfolge zur Folge gehabt:
...
<div>
<p>iii) A Listenelement</p>
<p>i) B Listenelement</p>
<p>ii) C Listenelement</p>
</div>
...
Die Buchliste sortiert und nummeriert
Dies lässt sich auch auf die nach Titeln sortierte Buchliste anwenden. Werden die Bücher mit <xsl:number format="001.) "/> nummeriert, ohne die Sortierung zu berücksichtigen, so wird die Nummerierung durcheinander gewürfelt:
009.) Aale im Streiflicht von Braun, Bert;
Verlag: Ozean Verlag; Preis: 14.00 Euro
(ISBN: 3-890-77608-5)
013.) Another Dog's Guide von Murr, Kater;
Verlag: Miau Publishing; Preis: 23.95 Dollar
(ISBN liegt nicht vor.)
023.) Another Hitchhiker's Guide to the Galaxy von Adams, Douglas;
Verlag: Spacetrotter Publishing; Preis: 15.00 Dollar
(ISBN: 3-899-77617-4)
Mit dem value-Attribut lässt sich dies leicht beheben:
<xsl:number format="001.) " value="fn:position()"/>
Das Ergebnis sieht jetzt wieder ordentlich aus:
001.) Aale im Streiflicht von Braun, Bert;
Verlag: Ozean Verlag; Preis: 14.00 Euro
(ISBN: 3-890-77608-5)
002.) Another Dog's Guide von Murr, Kater;
Verlag: Miau Publishing; Preis: 23.95 Dollar
(ISBN liegt nicht vor.)
003.) Another Hitchhiker's Guide to the Galaxy von Adams, Douglas;
Verlag: Spacetrotter Publishing; Preis: 15.00 Dollar
(ISBN: 3-899-77617-4)
Bislang wurden Sequenzen verarbeitet, die durch xsl:apply-templates zusammengestellt wurden. XSLT stellt hierfür jedoch weitere Möglichkeiten zur Verfügung, und zwar in Form der Schleifeninstruktionen. Diese können Sequenzen nicht nur zusammenstellen, sondern verarbeiten sie auch noch selbst.
<< 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