Laufzeitidentifier für Elemente – generate-id()
(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 3.)
Die Funktion generate-id() ermöglicht es, Elementen für den Zeitraum der XSLT-Verarbeitung (Laufzeit des Stylesheets) individuelle Identifier zuzuordnen. Generiert wird ein XML-Name. Es wird nach einem prozessor-spezifischen Algorithmus ein String aus ASCII-Zeichen erzeugt, der, auch dokumentübergreifend, für keine zwei Knoten identisch ist.
Dieser Identifier beginnt stets mit einem Buchstaben. Dadurch ist gewährleistet, dass es sich bei dem erzeugten Identifier immer um einen gültigen XML-Namen (NMToken) handelt. Abgesehen von dieser Einschränkung ist es jeder Anwendung freigestellt, wie die von ihr generierten Identifier aussehen.
Die Identifier sind virtuell, werden also nicht direkt gespeichert. Sie helfen dem Prozessor, sich ein bestimmtes Element zu merken: Man kann den Vorgang in der Form visualisieren, dass zum Zeitpunkt des ersten Aufrufs der Funktion generate-id() in Zusammenhang mit einem bestimmten Element dem Elementknoten ein Property mit dem generierten Identifierwert beigegeben wird. Bei allen folgenden Aufrufen wird dieses Property nur noch ausgelesen, aber nicht mehr neu belegt. Der genaue Wert des Identifiers ist nicht beeinflussbar – sichergestellt ist nur, dass er sich für den Zeitraum der Verarbeitung nicht verändert.
Automatisches Inhaltsverzeichnis mit generate-id()
Ein potenzielles Einsatzgebiet von generate-id() ist die automatische Erzeugung von ID-IDREF-Beziehungen, wie sie im Fall der HTML-Ausgabe für dokumentinterne Links der Form <a name="id"> und <a href="#id"> genutzt werden können.
Ein XML-Dokument <dokument> besteht aus mehreren Kapiteln <kapitel>, die jeweils einen Titel <titel> und einen Text <text> besitzen:
<dokument>
<kapitel>
<titel>Identifier mit Verfallszeit</titel>
<text>Die Funktion generate-id() ermöglicht es, Elementen für den Zeitraum der XSLT-Verarbeitung (Laufzeit des Stylesheets) individuelle Identifier zuzuordnen. ...</text>
</kapitel>
...
</dokument>
Aus dem Titelelement des Kapitels wird ein Inhaltsverzeichnis generiert, das gleichzeitig als Liste von Sprunglinks <a href="#..."> zu den entsprechenden, mit id-Attribut gekennzeichneten Kapiteln im Textblock des Dokuments dienen soll. Hierbei wird auch der korrespondierende id-Wert mittels generate-id() erzeugt. Die Funktion wird also stets zweimal in Zusammenhang der verarbeitung des Elements <title> aufgerufen:
Das erste Mal:
Beim Erstellen des Verzeichnisses wird der erzeugte Identifier mit einem Attributwert-Template als href-Attributwert eines Links verwendet. Durch die xsl:for-each-Schleife wird eine Sequenz aus allen <titel>-Elementen gebildet, die alle nacheinander Current Node werden. In diesem Augenblick wird die generate-id()-Funktion aufgerufen. Da diese hier kein Argument übergeben bekommt, bezieht sich der erzeugte Identifier automatisch auf den Current Node, also das aktuelle <titel>-Element der Schleife.
Das zweite Mal:
Bei der Ausgabe des Kapitels wird die Funktion das zweite Mal aufgerufen. Hier wird generate-id() mit einem NodeTest als Argument aufgerufen, der das <titel>-Child-Element des »aktuellen« Kapitels als Ziel hat. Der ausgegebene <titel>-Identifier korrespondiert zwangsläufig mit dem oben vergebenen und kann so zur Generierung eines id-Attributwerts, der hier als Linkziel dient, eingesetzt werden.
<xsl:template match="/">
<html>
<head>
<title>XSLT 2.0 und XPath 2.0: generate-id()</title>
</head>
<body>
<h1>Inhaltsverzeichnis mit generate-id()</h1>
<ul>
<xsl:for-each select="//titel">
<li><a href="#{generate-id()}"><xsl:value-of select="."/></a></li>
</xsl:for-each>
</ul>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="kapitel">
<h3 id="{generate-id(titel)}"><xsl:value-of select="titel"/></h3>
<p><xsl:value-of select="text"/></p>
<p><a href="#">nach oben</a></p>
<hr width="60%" noshade="noshade" size="1"/>
</xsl:template>
Code-Beispiel: kap03/3.10/generate-id.xsl (Ausschnitt).
Es spielt nicht wirklich eine Rolle, wann und wo die »virtuellen« IDs erzeugt werden. Die Reihenfolge der Funktionsaufrufe hat hier also nur Einfluss auf das Erscheinen der Ergebniselemente im Ausgabedokument.
Die so erzeugten Marker können während der Verarbeitung nicht über die id()-Funktion gefunden werden – es handelt sich auch um keine echte ID in diesem Sinne. Die Funktion id() findet nur »real« im XML-Dokument befindliche und als solche deklarierte Identifier. Hierfür wird eine DTD oder ein Schema benötigt.
<< 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