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 zuzuord­nen. 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ährleis­tet, 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 Vor­gang 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 beigege­ben wird. Bei allen folgenden Aufrufen wird dieses Property nur noch ausgele­sen, aber nicht mehr neu belegt. Der genaue Wert des Identifiers ist nicht beeinflussbar – sichergestellt ist nur, dass er sich für den Zeitraum der Verarbei­tung nicht verändert.

Automatisches Inhaltsverzeichnis mit generate-id()

Ein potenzielles Einsatzgebiet von generate-id() ist die automatische Erzeu­gung von ID-IDREF-Beziehungen, wie sie im Fall der HTML-Ausgabe für doku­mentinterne 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 entsprechen­den, 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 Iden­tifier mit einem Attributwert-Template als href-Attributwert eines Links ver­wendet. 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>-Ele­ment 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« Kapi­tels als Ziel hat. Der ausgegebene <titel>-Identifier korrespondiert zwangs­lä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 befind­liche 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