XPath 3.0, XPath 2.0, XPath 1.0 / XPath Funktionen / XPath: Sequence-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.

Je nach verwendetem Prozessor kann die Auswertung von Attributwerten zu Fehlern führen. Nehmen wir dieses XML Input Dokument als Beispiel:


<Menschen>
  <Mensch Nachname="Wunschlos" />
  <Mensch Nachname="Hilflos" />
  <Mensch Nachname="Nixlos" />
</Menschen>

Bei der Verarbeitung der "Nachname"-Attribute in kann es vorkommen, daß 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 wir 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, so daß 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 / 9. Februar 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse







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