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