XSLT

Aus Joachim Schuster Wiki
Wechseln zu: Navigation, Suche

Hier entsteht eine Sammlung von Informationen rund um die Transformation von XML via XSLT.

Inhaltsverzeichnis

* vs node()

Der * Operator matcht alle Elemente, wohingegen node() alle Knoten, also auch Text matcht.

<element>TEXT<inlineImage src='foo'/></element>

so würde ein template das auf * matcht nur das innere Element inlineImage verarbeiten.
Ein Match auf node() verarbeitet sowohl den Text als auch das inlineImage.

copy-of vs value-of

Beispiel:

<element>Text <foo>kindtext</foo> weiterer text</element>

value-of liefert den Wert des selektierten Knotens, bzw. inklusive dessen Kindknoten.

<xsl:value-of select="element"/>

liefert

Text kindtext weiterer text

copy-of liefert den Knoten inklusive seiner Kindknoten.

<xsl:copy-of select="."/>

liefert

<element>Text <foo>kindtext</foo> weiterer text</element>

find first or last element

Um das erste bzw. letzte Element eines bestimmten Typs zu finden kann im einfachsten Fall

<xsl:value-of select="//element[1]"/>

bzw.

 <xsl:value-of select="//element[last()]"/>

verwenden.

Dies liefert aber unter Umständen ein unerwartetes/falsches Ergebnis. Hier wird über den gesamten Baum nach element gesucht. Das [1] bedeutet, dass ein element, das an erster Stelle steht, ermittelt wird. Ebenso bedeutet, dass bei last() das element ermittelt wird, das an letzter Stelle steht. Diese umständliche Ausdrucksweise wird hier deutlich:

<doc>
 <chapter name="first">
  <element name="1.1"/>
  <element name="1.2"/>
 </chapter>
 <chapter name="second">
  <element name="2.1"/>
  <element name="2.2"/>
 </chapter>
</doc>

Der Ausdruck //element[1] wird 2 Elemente als Rückgabewert liefern. Weil die Bedinung [1] hier auf den Kontext und nicht auf das gesamte Dokument bezogen angewendet wird. Die Ergebnismenge wäre also element 1.1 und element 2.1. Analog würde es sich für den Ausdruck //element[last()] ergeben.

Möchte man aber nun wirklich das erste element und wirklich nur dieses haben, so muss man die den Ausdruck klammern, oder die ermittelten Elemente über eine for-each auswerten.

Klammern

<xsl:value-of select="(//element)[1]"/>

bzw.:

<xsl:value-of select="(//element)[last()]"/>

for-each

Darin wird die Ergebnismenge unabhängig von der Dokumentstruktur behandelt, sodass das erste bzw. letzte Element korrekt ermittelt wird.

<xsl:for-each select="//element">
 <xsl:if test="position() = 1">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each> 

bzw.:

<xsl:for-each select="//element">
 <xsl:if test="position() = last()">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each>

Links

[1]