XSLT

Aus Joachim Schuster Wiki
Wechseln zu: Navigation, Suche

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

* 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 ermittelten Elemente über eine foreach auswerten. 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="@name"/>
 </xsl:if>
</xsl:for-each> 

bzw.:

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