XPath: Pfade bestimmen
Um auf einen Knoten zeigen zu können, wird vom aktuellen Knoten aus ein bestimmter Pfad definiert, den der Interpreter abschreiten muss um zu dem jeweiligen Knoten oder der jeweiligen Knotenmenge zu gelangen. XPath definiert dazu eine Reihe von syntaktischen Hilfsmitteln mit denen die Definition solcher Pfade möglich ist.Relative Pfade und absolute Pfade
XPath unterscheidet zwischen relativen und absoluten Pfaden. Ein relativer Pfad geht von dem Knoten aus an dem sich der Interpreter gerade befindet. D.h. befindet sich der Interpreter gerade innerhalb des Elementbaumes geht ein relativer Pfad von diesem Knoten innerhalb des Elementbaums aus und zeigt dann auf einen anderen Knoten/Knotenmenge innerhalb des Baumes.Jeder Schritt zu einem anderen Knoten oder einer anderen Knotenmenge wird durch ein
/
von den anderen abgetrennt. Als Beispiel sei folgende XML-Datei gegeben:
<a>
<b>
<c></c>
<c></c>
</b>
</a>
<b>
und möchte von da aus nun auf den ersten Knoten <c> zeigen, so geschieht dies mittels dem Pfad:
child::c[position() = 1]
Das Wortchild
gefolgt von zwei Doppelpunkten gibt dabei an, dass ein Kindknoten des aktuellen Knotens gesucht wird. Nach dem Doppelpunkt folgt die Angabe des Namens, nach welchem Knoten gesucht wird (der erweiterte Name des Knotens). Innerhalb der eckigen Klammern steht dann die Position des zu suchenden Knotens. Nur child::
c allein würde eine Knotenmenge liefern (alle Kindknoten mit dem erweiterten Namen c
), deshalb wird so angegeben, dass nur der Knoten an der Position 1 gefunden werden soll.Möchte man vom Knoten
<a>
auf eben diesen ersten <c>
-Knoten zeigen, so geschieht dies durch zwei Schritte, die dementsprechend durch ein /
getrennt werden: child::b[position() = 1]/child::c[position() = 1]
Absolute Pfade sind Pfade die vom Rootknoten ausgehen. Sie beginnen immer mit einem/
gefolgt vom (absoluten) Pfad zum entsprechenden Zielknoten/Zielknotenmenge. D.h. egal an welcher Stelle innerhalb des Elementbaums der Interpreter steckt mittels des folgenden Pfades gelang man immer zum ersten <c>
-Knoten:
/child::b[position() = 1]/child::c[position() = 1]
Schritte definieren
Wie oben schon annähernd deutlich geworden ist, lassen sich die einzelnen Schritte die zu dem nächsten Knoten innerhalb des Pfades führen sehr exakt definieren. XPath liefert dazu eine Reihe von Hilfsmitteln mit denen ein Schritt sehr genau definiert werden kann. Jeder Schritt besteht dabei aus der Achse, einem Knotentest sowie optional einem oder mehreren Prädikaten.Achsen
Für die Beschreibung einer Achse können mehrere durch XPath definierte Wörter verwendet werden. Die folgende Tabelle listet diese Wörter auf und verwendet als Grundlage der Beschreibung den folgenden Quellcode:<a> [a1]
<b> [b1]
<c /> [c1]
<c /> [c2]
<c /> [c3]
<c /> [c4]
</b>
<b> [b2]
<d> [d1]
<e /> [e1]
<e /> [e2]
</d>
<d> [d2]
<e /> [e3]
<e /> [e4]
</d>
</b>
</a>
Achse | Beschreibung |
---|---|
child | Liefert alle Kindknoten des aktuellen Knotens. Für den Knoten b2 sind das die Knoten d1 und d2. Kinder sind niemals Attributknoten. |
descendant | Liefert alle Nachkommen des aktuellen Knotens. Für den Knoten b2 sind das die Knoten d1, e1, e2, d2, e3 und e4. Nachkommen sind niemals Attributknoten. |
parent | Liefert den Elternknoten (sofern es einen gibt) des aktuellen Knotens. Für den Knoten b2 ist das der Knoten a1, für d2 ist das b2, für e3 ist das d2 usw. Für den Elternknoten von a1 wird nichts ausgegeben. |
ancestor | Liefert alle Vorfahren (sofern es sie gibt) des aktuellen Knotens. Für den Knoten d2 sind das die Knoten b2 und a1, für e1 sind das d1, b2 und a1 usw. |
following-sibling | Liefert alle nachfolgenden Geschwisterknoten des aktuellen Knotens. Für den Knoten b1 ist das der Knoten b2. Für c1 ist das c2, c3 und c4. Der Knoten c4 hat keine entsprechenden Knoten. |
preceding-sibling | Liefert alle vorhergehenden Geschwisterknoten des aktuellen Knotens. Für den Knoten c4 sind das die Knoten c3, c2 und c1. Für c1 gibt es keinen solchen Knoten. |
following | Liefert alle Knoten die nachfolgende Geschwisterknoten oder deren Nachkommen sind. Für den Knoten b1 sind das: b2, d1, e1, e2, d2, e3 und e4. |
preceding | Liefert alle Knoten die innerhalb der Dokumentstruktur vor dem aktuellen Knoten liegen aber keine Vorfahren des aktuellen Knotens sind. Für den Knoten e4 sind das: e3, d1, e1, e2, b1, c1, c2, c3 und c4 |
attribute | Liefert alle Attributknoten des aktuellen Knotens. Dies gibt nur bei Elementknoten einen Erfolg aus. |
namespace | Liefert alle Namensraumknoten des aktuellen Knotens. Dies gibt nur bei Elementknoten einen Erfolg aus. |
self | Liefert den aktuellen Knoten. |
descendant-or-self | Liefert alle Knoten die Nachkommen oder der aktuelle Knoten selbst sind. Für den Knoten d2 sind das die Knoten d2, e3 und e4. |
ancestor-or-self | Liefert alle Knoten die Vorfahren oder der aktuelle Knoten selbst sind. Für den Knoten d2 sind das d2, b2 und a1. |
Knotentests
Mit Hilfe von Knotentests läßt sich die Suche nach dem gewünschten Knoten oder der gewünschten Knotenmenge noch näher beschreiben. Ein Knotentest ist dabei nichts weiter als eine zusätzliche Definition zu den oben genannten Achsendefinitionen. Als Knotentest können folgende Werte verwendet werden:-
Knotenname
- Wird ein Name angegeben, so wird innerhalb der Knotenmenge aus der Achsendefinition nach den Knoten gesucht die über einen solchen erweiterten Namen verfügen. Als Resultat erhält man damit die Knotenmenge der Knoten mit dem entsprechenden erweiterten Namen. -
*
- Der Stern bedeutet, dass alle Knoten innerhalb der Knotenmenge der Achsendefinition gefunden werden sollen - egal welchen Namen sie tragen. -
Präfix:Name
oderPräfix:*
- Bei Angabe eines Präfixes wird nach allen Knoten aus dem entsprechenden Namensraum gesucht die den angegebenen Namen erfüllen. Alternativ kann auch der Stern statt dem Namen verwendet werden - dann werden alle Knoten des Namensraums gefunden - egal welchen Namen sie tragen. -
text()
- Wählt alle Textknoten aus. -
comment()
- Wählt alle Kommentarknoten aus. -
processing-instruction()
- Wählt alle PI-Knoten aus. Optional kann als Parameter innerhalb der Klammern der Name der zu suchenden PI angegeben werden.processing-instruction('xml-stylesheet')
findet alle PI's mit dem Namenxml-stylesheet
. -
node()
- Wählt alle Knoten beliebigen Typs aus.
child::a
wählt alle Kindknoten mit dem Namen a aus
child::*
wählt alle Kindknoten aus
child::xhtml:h1
wählt alle Kindknoten aus dem XHTML-Namensraum aus, die h1
heissen
Prädikate
Prädikate dienen noch einmal der Verfeinerung einer Suche. Sie sind optional, werden dann aber immer in eckigen Klammern ([
und ]
) notiert. Innerhalb dieser Klammern kann ein nahezu beliebiger Ausdruck stehen der eine gültige Aussage liefert. Beispiel:
child::a[position() = 1]
wählt nur das erste Kindelement a aus.
child::a[last()]
wählt nur das letzte Kindelement a aus.
child::a[attribute::href = "/ziel.htm"]
wählt die Kindelemente a aus die ein Attribut href="/ziel.htm"
besitzen.
Verkürzung der Schreibweise
Da einige Formulierungen öfter verwendet werden, gibt es für diese verkürzte Schreibweisen.child:: weglassen
Da oftmals auf die Kindelemente des aktuellen Knotens zugegriffen werden muss, kann man sich dies vereinfachen indem manchild::
wegläßt. Man beginnt dann mit dem Knotennamen des zu suchenden Kindes. Beispiel:Lang:
child::a/child::b/child::c
Kurz:
a/b/c
/descendant-or-self::node()/ verkürzen
Des öfteren werden auch alle Nachkommenknoten verwendet. Um die relativ lange Schreibung von/descendant-or-self::node()/
zu verkürzen kann hierfür einfach nur // notiert werden. Beispiel:Lang:
/descendant-or-self::node()/a
Kurz:
//a
Attribute auswählen
Zur Auswahl eines Attributes kann statt der Schreibungattribute::Name
das @
-Zeichen verwendet werden. Es steht stellvertretend für attribute::
. Beispiel:Lang:
child::a[attribute::href = "/ziel.htm"]
Kurz:
a[@href = "/ziel.htm"]
Aktueller Knoten
Der aktuelle Knoten wird normalerweise mitself::node()
ausgewählt. Um diese Schreibung zu verkürzen kann, statt dessen der Punkt (.
) verwendet werden. Beispiel:Lang:
self::node()/parent::a
Kurz:
./parent::a
Elternknoten
Der Elternknoten wird normalerweise mitparent::node()
ausgewählt. Um diese Schreibung zu verkürzen, kann statt dessen der doppelte Punkt (..
/ nicht verwechseln mit dem Doppelpunkt) verwendet werden. Beispiel:Lang:
parent::node()/a
Kurz:
../a
Du arbeitest in einer Agentur oder als Freelancer?
Dann wirf doch mal einen Blick auf unsere Software FeatValue.
Weiterlesen: ⯈ Funktionen
Über uns

Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project