XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / XPath: Sequenz-Funktionen / XPath: data

XPath: data

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

Auswertung von xsl:attribute-set

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.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/data.html