XPath / XPath-Funktionen / XPath: Sequenz-Funktionen / XPath: data
![]() |
![]() |
➪ Die data()-Funktion liefert die atomisierten Werte einer Sequenz: Jeder Node wird also durch seinen Wert ersetzt. Das ist besonders wertvoll bei der Verarbeitung von Attributen.
Auf dieser Seite:Je nach verwendetem Prozessor kann die Auswertung von Attributwerten zu Fehlern führen. Nehmen Sie dieses XML-Input-Dokument als Beispiel:
<Menschen>
<Mensch Nachname="Wunschlos" />
<Mensch Nachname="Hilflos" />
<Mensch Nachname="Nixlos" />
</Menschen>
Bei der Verarbeitung der Nachname-Attribute in XQuery kann es vorkommen, dass das Attribut nicht ausgewertet, sondern kopiert wird.
<zielstruktur>
{
for $m in /Menschen/Mensch
return
<p>{$m/@Nachname}</p>
}
</zielstruktur>
Das (nicht gewünschte) Ergebnis sehen Sie hier:
<zielstruktur>
<p Nachname="Wunschlos"/>
<p Nachname="Hilflos"/>
<p Nachname="Nixlos"/>
</zielstruktur
Die Verarbeitung über <p>{$m/@Nachname/text()}</p> generiert drei leere <p>-Elemente; das ist ebenfalls nicht gewünscht. Hilfreich ist entweder die Arbeit mit der String-Konvertierung
<p>{$m/xs:string(@Nachname)}</p>
... oder über die data()-Funktion:
<zielstruktur>
{
for $m in /Menschen/Mensch
return
<p>{data($m/@Nachname)}</p>
}
</zielstruktur>
Das gewünschte Ergebnis lautet dann:
<zielstruktur>
<p>Wunschlos</p>
<p>Hilflos</p>
<p>Nixlos</p>
</zielstruktur>
Das folgende Beispiel generiert eine Sequenz aus mehreren Elementen (//name kommt aus dem XML-Input, $v/E/attribute::* ist eine Attributliste). Während bei der Auswertung von //name im Grunde //name/text() ausgegeben wird, das in <xsl:value-of select="./text()" /> auch gezielt aufgerufen werden kann, würde dieser ./text()-Aufruf bei den Attributen einen leeren Output ergeben.
<xsl:attribute-set name="aset1">
<xsl:attribute name="a1">a1</xsl:attribute>
<xsl:attribute name="a2">a2</xsl:attribute>
</xsl:attribute-set>
<xsl:template name="data_function">
<Liste>
<xsl:variable name="v">
<E xsl:use-attribute-sets="aset1" />
</xsl:variable>
<xsl:for-each select="(//name, $v/E/attribute::*)">
<wert>
<xsl:value-of select="./text()" />
</wert>
</xsl:for-each>
</Liste>
</xsl:template>
Bei Aufruf eines XML-Input Dokumnts, das an beliebiger Stelle die Elemente <name>Muehelos</name> und <name>Leinenlos</name> beinhaltet, ergäbe der Aufruf des oben beschriebenen XSL-Stylesheets folgendes Resultat:
<Liste>
<wert>Muehelos</wert>
<wert>Leinenlos</wert>
<wert/>
<wert/>
</Liste>
data() atomisiert nun diese Sequenz, sodass unterschiedslos mit den Einzelwerten gearbeitet werden kann. Freilich würde eine Auswertung dieser atomisierten Sequenz mit <xsl:value-of select="./text()" /> eine Fehlermeldung verursachen: "Fatal Error! Required item type of first operand of '/' is node(); supplied value has item type xs:anyAtomicType".
<xsl:template name="data_function">
<Liste>
<xsl:variable name="v">
<E xsl:use-attribute-sets="aset1" />
</xsl:variable>
<xsl:for-each select="data((//name, $v/E/attribute::*))">
<wert>
<xsl:value-of select="." />
</wert>
</xsl:for-each>
</Liste>
</xsl:template>
Das Resultat ist nun wie gewünscht:
<Liste>
<wert>Muehelos</wert>
<wert>Leinenlos</wert>
<wert>a1</wert>
<wert>a2</wert>
</Liste>
wg / 12. April 2018
Fragen? Anmerkungen? Tipps?
Bitte nehmen Sie Kontakt zu mir auf.
V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn
☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de