XML | XML-Schema | XPath | XSL-T | XSL-FO | XQuery | XProc | SVG |
XPath / XPath-Achsen / preceding-sibling::*
![]() |
![]() |
➪ Mit preceding-sibling::* erhalten Sie Vorgänger-Nodes des aktuellen Knotens.
Auf dieser Seite:Analog zu following-sibling::* finden Sie die Wirkung bei preceding-sibling::*. Bezogen auf den klar adressierten Node /Orte/Ort[1]/Mensch[4], erhalten Sie sämtliche vorhergehenden Nodes auf derselben Ebene, unabhängig von ihrem Node-Name.
<xsl:template match="/">
<ergebnis>
<xsl:for-each
select="/Orte/Ort[1]/Mensch[4]
/preceding-sibling::*">
<e nr="{position()}">
<xsl:call-template name="generateXPath"/>
</e>
</xsl:for-each>
</ergebnis>
</xsl:template>
Das Resultat lautet dann zum Beispiel:
<ergebnis>
<e nr="1">/Orte/Ort[1]/id[1]</e>
<e nr="2">/Orte/Ort[1]/name[1]</e>
<e nr="3">/Orte/Ort[1]/Mensch[1]</e>
<e nr="4">/Orte/Ort[1]/Mensch[2]</e>
<e nr="5">/Orte/Ort[1]/Mensch[3]</e>
</ergebnis>
Möchten Sie dagegen nur die vorhergehenden Nodes eines bestimmten Namens ansprechen (also z.B. Mensch, die anderen Nodes id und name jedoch ignorieren), so lautet der Ausdruck:
<xsl:for-each
select="/Orte/Ort[1]/Mensch[4]
/preceding-sibling::Mensch">
...
</xsl:for-each>
Dann sieht das Ergebnis (bei demselben Input-Dokument) so aus:
<ergebnis>
<e nr="1">/Orte/Ort[1]/Mensch[1]</e>
<e nr="2">/Orte/Ort[1]/Mensch[2]</e>
<e nr="3">/Orte/Ort[1]/Mensch[3]</e>
</ergebnis>
Siehe auch
Freilich erscheint der Zugriff etwas mißverständlich. Für folgenden XML Import:
<A>
<B1/>
<B2/>
<B3/>
<B4/>
<B5/>
<B6/>
<B7/>
<B8/>
<B9/>
</A>
... und diesem XSLT-Quellcode:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/A/B5">
<ergebnis>
<xsl:for-each select="./preceding-sibling::*">
<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>B1</Element>
<Element>B2</Element>
<Element>B3</Element>
<Element>B4</Element>
</ergebnis>
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="/A/B5">
<ergebnis>
<xsl:for-each select="./preceding-sibling::*[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>B4</Element>
</ergebnis>
Siehe auch intersect.
Während Sie mit preceding-sibling die Vorläufer eines gewählten Nodes ansprechen, ermitteln Sie mit following-sibling die jeweiligen Nachfolger. Letzteres wird in Kombination mit der count-Funktion interessant, um einen Countdown durchzuführen. Die folgende Nodeliste bezieht sich auf einen gewählten Mensch-Node (last()) und dessen Vorgänger. Die position()-Funktion klärt die Reihenfolge, count(following-sibling::Mensch) berechnet die Anzahl der restlichen Nodes bis zum gewählten letzten Node.
<xsl:template match="/">
<ergebnis>
<xsl:for-each
select="/Orte/Ort[1]/Mensch[last()]
/preceding-sibling::Mensch,
/Orte/Ort[1]/Mensch[last()]">
<e nr="{position()}"
countdown="{count(following-sibling::Mensch)}">
<xsl:value-of
select="concat(vorname, ' ', name)"/>
</e>
</xsl:for-each>
</ergebnis>
</xsl:template>
Alternativ hätten Sie das "countdown"-Attribut auch so implementieren können:
countdown="{count(following-sibling::*[name(.)=name(current())])}"
Das Ergebnis verdeutlicht das Vorgehen. "Heini Herzlos" als letztes Element der Liste steht auf nr. 6, während sämtliche Vorläufer durchnummeriert werden.
<ergebnis>
<e nr="1" countdown="5">Hugo Holzflos</e>
<e nr="2" countdown="4">Nicole Nixlos</e>
<e nr="3" countdown="3">Stefan Sprachlos</e>
<e nr="4" countdown="2">Stefan Sagblos</e>
<e nr="5" countdown="1">Siggi Sorglos</e>
<e nr="6" countdown="0">Heini Herzlos</e>
</ergebnis>
wg / 14. März 2021
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