C#.NET * C++ * JAVASCRIPT * PYTHON * XML
* XML-SCHEMA * XPATH * XSL * XSL-FO * SVG * XQUERY * XPROC



XPath / XPath-Achsen / descendant-or-self::*

descendant-or-self::*

descendant-or-self::*

➪ Mit descendant-or-self::* erhalten Sie den aktuellen Node und dessen sämtliche Nachkommen.

Auf dieser Seite:

pic/XPath_descendantorself.jpg


 <xsl:template match="/">
  <ergebnis>
   <xsl:for-each 
        select="/Orte/Ort[1]
                /descendant-or-self::*">
    <e nr="{position()}">
     <xsl:call-template name="generateXPath"/>
    </e>
   </xsl:for-each>
  </ergebnis>
 </xsl:template>

Evtl. etwas mißverständlicher Zugriff

Siehe auch

Freilich erscheint der Zugriff etwas mißverständlich. Für folgenden XML Import:


<?xml version="1.0" encoding="utf-8" ?>
<A0>
  <A1>
    <A2>
      <A3>
        <A4>
          <A5>
            <A6>
              <A7>
                <A8>
                  <A9/>
                </A8>
              </A7>
            </A6>
          </A5>
        </A4>
      </A3>
    </A2>
  </A1>
</A0>

... und diesem XSLT-Quellcode:


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/A0/A1/A2/A3">
    <ergebnis>
      <xsl:for-each select="./descendant-or-self::*">
        <Element>
          <xsl:value-of select="name()"/>
        </Element>
      </xsl:for-each>
    </ergebnis>
    </xsl:template>
</xsl:stylesheet>

... lautet das Ergebnis:


<?xml version="1.0" encoding="UTF-8"?>
<ergebnis>
   <Element>A3</Element>
   <Element>A4</Element>
   <Element>A5</Element>
   <Element>A6</Element>
   <Element>A7</Element>
   <Element>A8</Element>
   <Element>A9</Element>
</ergebnis>

Ergebnis bei erstem Wert

Bei demselben XML-Input und folgendem XSLT-Code


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/A0/A1/A2/A3">
        <ergebnis>
            <xsl:for-each select="./descendant-or-self::*[1]">
                <Element>
                    <xsl:value-of select="name()"/>
                </Element>
            </xsl:for-each>
        </ergebnis>
    </xsl:template>
</xsl:stylesheet>

... lautet das Ergebnis dagegen (also nur der direkt vorhergehende Wert):


<?xml version="1.0" encoding="UTF-8"?>
<ergebnis>
   <Element>A3</Element>
</ergebnis>

XML-Schema Analyse mit descendant-or-self::*

Auch bei der Strukturanalyse von XML-Schema ist die Arbeit mit descendant-or-self::* und ancestor-or-self::* hilfreich. Angenommen, Ihnen liegt () XML-Schema vor, und Sie möchten eine Liste aller Elemente haben.


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="Orte" >
  <xs:complexType>
   <xs:choice maxOccurs="unbounded">
    <xs:element name="Ort">
     <xs:complexType>
      <xs:sequence>
       <xs:element name="id" type="xs:int" />
       <xs:element name="name" type="xs:string" />
       <xs:element name="Mensch" minOccurs="0" 
                                 maxOccurs="unbounded">
        <xs:complexType>
         <xs:sequence>
          <xs:element name="id" type="xs:int" />
          <xs:element name="name" type="xs:string" />
          <xs:element name="vorname" type="xs:string" />
          <xs:element name="Gehalt" type="xs:string" />
          <xs:element name="idOrt" type="xs:int" />
          <xs:element name="Kauf" minOccurs="0" 
                                  maxOccurs="unbounded">
           <xs:complexType>
            <xs:sequence>
             <xs:element name="idMensch" type="xs:int" />
             <xs:element name="anzahl" type="xs:int" />
             <xs:element name="bez" type="xs:string" />
             <xs:element name="preis" type="xs:double" />
             <xs:element name="Gesamt" type="xs:double" />
            </xs:sequence>
           </xs:complexType>
          </xs:element>
         </xs:sequence>
        </xs:complexType>
       </xs:element>
      </xs:sequence>
     </xs:complexType>
    </xs:element>
   </xs:choice>
  </xs:complexType>
 </xs:element>
</xs:schema>

Bei der Auswertung hilft Ihnen das folgende XSL-Stylesheet:


<xsl:stylesheet 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
      <ergebnis>
        <xsl:for-each 
            select="/descendant-or-self::xs:element">
          <Element>
            <xsl:attribute name="XPath">
              <xsl:for-each select="ancestor-or-self::*">
                  <xsl:text>/</xsl:text>
                  <xsl:value-of select="name()"/>
              </xsl:for-each>
            </xsl:attribute>
            <xsl:value-of select="@name"/>
          </Element>
        </xsl:for-each>
      </ergebnis>
    </xsl:template>
</xsl:stylesheet>

Die Ausgabe beschert Ihnen eine xs:element-Liste sowie deren jeweiliger kompletter XPath.


<ergebnis xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <Element XPath="/xs:schema/xs:element">Orte</Element>
  <!-- sowie zahlreiche weitere -->
</ergebnis>

Möchten Sie lediglich jene Elementnamen haben, die an verschiedener Stelle mehrfach implementiert sind, so hilft Ihnen dieses XSL-Stylesheet weiter:


<xsl:template match="/">
  <ergebnis>
    <xsl:for-each-group 
         select="/descendant-or-self::xs:element" 
         group-by="@name">
      <xsl:if test="count(current-group()) &gt; 1">
        <Mehrfachdeklaration 
          name="{current-grouping-key()}">
          <xsl:for-each select="current-group()">
            <XPath>
              <xsl:for-each select="ancestor-or-self::*">
                <xsl:text>/</xsl:text>
                <xsl:value-of select="name()"/>
              </xsl:for-each>
            </XPath>
          </xsl:for-each>
        </Mehrfachdeklaration>
      </xsl:if>
    </xsl:for-each-group>
  </ergebnis>
</xsl:template>

Wie gewünscht, finden Sie in der Ausgabe lediglich die mehrfach deklarierten Elementnamen und deren jeweiliger XPath.


<ergebnis xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <Mehrfachdeklaration name="id">
   <XPath>/xs:schema/xs:element/xs:complexType/xs:choice
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element</XPath>
   <XPath>/xs:schema/xs:element/xs:complexType/xs:choice
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element</XPath>
  </Mehrfachdeklaration>
  <Mehrfachdeklaration name="name">
   <XPath>/xs:schema/xs:element/xs:complexType/xs:choice
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element</XPath>
   <XPath>/xs:schema/xs:element/xs:complexType/xs:choice
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element/xs:complexType/xs:sequence
                    /xs:element</XPath>
  </Mehrfachdeklaration>
</ergebnis>

wg / 14. März 2021



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.




parent::*



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/XPath_Achsen7.html