fn:id

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 5.)

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

   

Kategorie: Assoziation und Auffindung von Nodes und Ressourcen

Herkunft: XSLT 1.0 (nun auch Teil des XPath 2.0 Core)

Rückgabewert: Ein Nodeset (eine Sequenz), der aus Elementen mit jenen Identifierbezeichnern besteht, die sich aus der Auswertung des im Argument des Funktionsaufrufs übergebenen Wertes ergeben.

Aufruf/Argumente:

fn:id($stringsequenz, $node?)

$stringsequenz:
Obligatorisch. Eine Sequenz aus Strings xs:string, von denen jeder einzelne als durch Leerzeichen separierte Tokenliste aus IDREF-Werten behandelt wird. Wird der Funktion die leere Sequenz übergeben, so gibt sie diese zurück.

$node: (neu in XSLT 2.0)
Optional. Mit dem zweiten Argument kann ein beliebiger Knoten übergeben werden, der Teil des Dokument ist, innerhalb dessen die Funktion arbeiten soll. Wird die leere Sequenz übergeben, so bezieht sich die Funktion auf das beim Aufruf aktuelle Kontextdokument (dies entspricht dem Aufruf mit einem einzigen Argument). Dieses Argument steht in XSLT 1.0 nicht zur Verfügung.

Verwendungszweck:

Die Funktion fn:id() soll auf typgültige Doku­mente angewendet werden. Grundlage für ihren Einsatz ist das Vorhandensein einer DTD (oder eines Schemas), auf die zugegriffen werden kann und in der die Attribute vom Typ ID deklariert sind, die demzufolge über ein Property is-id verfügen. In einem Kontextdokument werden Elemente mit ID-Werten gesucht, die den der Funktion übergebenen IDREF-Werten entsprechen. Die Funktion gibt alle gefundenen Elementknoten in Dokumentreihenfolge als Sequenz aus, wobei Doubletten bei mehrfach erfassten Knoten aus der Sequenz entfernt werden.

Verhalten unter XSLT 2.0/XPath 2.0:

Die Liste der zu überprüfenden IDREF-Werte wird aus der übergebenen Stringsequenz generiert, indem jeder der Strings als eine Tokenliste aus IDREF-Kandidaten betrachtet wird, d.h., jeder String wird in Einzeltoken aufgespalten, wobei Leerzeichen als Begrenzer (Delimiter) dienen.

Jedes einzelne der so erzeugten Token muss lexikalisch den Anforderungen an den Typ IDREF entsprechen (also dem Typ xs:NCName entsprechen), ansonsten wird es verworfen bzw. ignoriert (es gibt hierbei keine Fehlermeldung).

Mit Hilfe der so gebildeten Liste aus Werten wird das Kontextdokument nach Elementen mit Attributen vom Typ ID durchsucht, die einen der IDREF-Kandi­datenwerte enthalten. Wird ein solches Element gefunden, so wird es der Ergebnissequenz hinzugefügt.

Die Gleichheit von ID- und IDREF-Kandidatenwert wird dabei anhand der Unicode-Werte (Codepoints) ihrer Zeichen bestimmt. Es wird keine Collation (auch nicht die Default-Collation) hinzugezogen, demzufolge ist unbedingte Identität in Bezug auf die Zeichenwerte erforderlich.

Mit Hilfe des optionalen zweiten Funktionsarguments kann ein alternatives Dokument bezeichnet werden, auf das sich die Funktion beziehen soll. Hierzu kann der Dokumentknoten dieses Dokuments oder ein beliebiger anderer Knoten übergeben werden, der Teil des Dokuments ist. Es ist jedoch ein Fehler, wenn ein Knoten übergeben wird, dessen Baum keinen Dokumentknoten als Wurzelelement besitzt (»No context document«,  err:FODC0001).

Wird kein zweites Argument übergeben und existiert zum Zeitpunkt des Funk­tionsaufrufs kein Kontextknoten, so ist das Kontextdokument nicht bestimmbar was einen Laufzeitfehler zur Folge hat (err:XPDY0002). Existiert ein Kontextitem, aber handelt es sich bei ihm nicht, wie gefordert, um einen Knoten, so erfolgt die Typfehlermeldung err:XPTY0004.

Sonderfälle:

Ist das übergebene Argument leer oder nicht in einen String umwandelbar, der einem erlaubten Identifier entspricht (z.B. bei einem String aus Ziffern), so wird eine leere Sequenz (ein leerer Nodeset) zurückgegeben. Entsprechend werden aus Ziffern bestehende Token, die in einer Tokenliste auftreten, ignoriert (da sie lexikalisch nicht den Anforderungen genügen, siehe oben).

Ist die DTD oder das Schema zum Dokument nicht zugänglich oder wird das Dokument durch einen nicht validierenden XML-Parser eingelesen, so gibt die Funktion (vorsichtshalber) eine leere Sequenz zurück, da den vorliegenden Attributen nicht zuverlässig der Typ ID zugeordnet werden kann.

Liegt eine DTD oder ein Schema vor und das Dokument ist durch Doppelver­gabe eines Identifierwertes nicht typgültig, so wird in diesem Fall das erste Element in Dokumentreihenfolge mit dem gesuchten ID-Wert in den Ergebnis­nodeset übernommen.

ID-Attribute und Attribute namens »id«:
Hat das Identifier-Attribut neben dem Typ ID auch den Bezeichner »id«, so entspricht der Funktionsaufruf fn:id('wert') im Ergebnis dem XPath-Ausdruck //*[@id='wert']. Die Verwendung von fn:id() wird allerdings in der Regel in der Verarbeitung schneller sein. Die Funktion kann jedoch nur auf »echte« in der DTD als Atribute vom Typ ID deklarierte Iden­tifier angewendet werden – dann allerdings unabhängig vom eigentlichen Bezeichner des Attributs (der wirkliche Bezeichner des Attributs muss nicht bekannt sein!). Die Funktion betrachtet alle Attribute, die ein is-id-Property besitzen.

Verhalten unter XSLT 1.0/XPath 1.0:

In XSLT 1.0 kann der übergebene Wert von beliebigem Typ sein, also beispielsweise sowohl einen einzelnen String als auch einen Nodeset darstellen. Ist der übergebene Wert kein Node­set, sondern ein beliebiger atomarer Wert, so wird er gemäß der Funktion string() in einen String verwandelt.

Handelt es sich bei dem übergebenen Argument um einen Nodeset, so wird jeder einzelne im Nodeset enthaltene Node zu einem String konver­tiert. Dies entspricht nicht der gewöhnlichen Umwandlung eines Nodesets durch string(), da in jenem Fall nur der erste Node des Sets umgewandelt würde.

Das Verhalten ist ansonsten analog zum oben beschriebenen. Rückgabewert ist allerdings in diesem Fall formal ein Nodeset aus Elementen mit den gesuchten ID-Werten. Im Gegensatz zur XPath 2.0-Version nimmt id() allerdings nur maximal ein Argument entgegen. Es ist daher nicht möglich, der Funktion unmittelbar ein anderes Dokument zu übergeben. Umgehen lässt sich dieser Umstand jedoch mit folgender XPath-Konstruktion:

$externes-dokument/id($vergleichswert)

Übergabe einer IDREFS-Tokenliste:
Die Übergabe einer Tokenliste lässt sich durch die Übergabe eines IDREFS-Attributwertes an die Funk­tion realisieren:

fn:id(@IDREFS-Attribut)

Werden im geteste­ten Dokument keine zu den übergebenen Identifiern passenden Elemente gefunden, so ist der Ergebnisnodeset leer. Dies stellt keinen Fehler dar.

Mögliche Kompatibilitätsprobleme XPath 2.0 zu XPath 1.0:
In XPath 2.0 ergibt der Ausdruck fn:id(fn:true()) einen Typfehler (type error), da die Funktion einen String xs:string erwartet. XPath 1.0 wandelt den booleschen Eingabewert hingegen in einen String um und sucht anschließend nach einem Element mit dem ID-Wert true. Ebenso stellt in XPath 2.0 auch die Übergabe einer Zahl einen Typfehler dar. In XPath 1.0 resultiert ein Ausdruck wie id(17) dagegen lediglich in einem leeren Nodeset.

Beispiel – Auflösung einer Beziehung von IDREFS nach ID:

Mit fn:id() werden Eingangswerte vom Typ IDREF verarbeitet und es werden die Elemente mit dem entsprechenden ID-Attribut gesucht.

Ein Buch kann mehrere Autoren besitzen, die vom <buch>-Element über ein IDREFS-Attribut autoren referenziert werden.

<buch autoren="autor1 autor2 autor3">Beispieltitel</buch>

Die Autorenelemente besitzen jeweils ein Attribut vom Typ ID, dessen Wert mit einem Token der IDREFS-Liste eines Buches korrespondiert. Das Attribut muss allerdings nicht notwendigerweise auch den Bezeichner id besitzen:

<autor id="autor1">
  <vorname>Berhard</vorname>
  <nachname>Beispielautor</nachname>
</autor>

Current Node ist ein Element <buch>. Bei der Verarbeitung kann der Wert sei­nes IDREFS-Attributs autoren als Argument der Funktion fn:id() verwendet werden, um alle <autor>-Elemente zu finden, auf deren jeweilige ID eine der Referenzen zeigt:

<xsl:template match="buch">...geschrieben von 
  <xsl:for-each select="fn:id(@autoren)">
    <!-- Sequenz aus allen am Buch beteiligten Autoren -->
    <xsl:value-of select="vorname"/>
      <xsl:text> </xsl:text>
    <xsl:value-of select="nachname"/>
    <xsl:if test="fn:position() != fn:last()">, </xsl:if>
    <xsl:if test="fn:position() = fn:last()"> und </xsl:if>
  </xsl:for-each>
</xsl:template>

Als Ergebnis wird die Liste aller Autoren ausgegeben, die am Buch beteiligt waren und deren ID-Identifier im IDREFS-Attribut autoren des <buch>-Ele­ments referenziert wird.

Funktionsdefinition:

XSLT 1.0:

id(object) => node-set

XPath 2.0/XSLT 2.0:

fn:id($arg as xs:string*) as element()*

fn:id($arg as xs:string*, $node as node()) as element()*

   

<< 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