Die Predicates (Filterbedingungen)

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 4.)

Die nach dem Achsenschritt verbliebene Knotenmenge kann durch weitere Bedingungen, die Predicates, zusätzlich eingeschränkt werden.

Der Achsenschritt muss zunächst erfüllt sein. Erst anschließend werden für jeden daraus resultierenden Knoten die Predicates nacheinander ausgewertet. Die Auswertung erfolgt von links nach rechts, wobei jeder Ausdruck das Ergeb­nis des Vorgängerausdrucks filtert.

Der Predicate-Ausdruck besteht aus einem XPath-Ausdruck, der einen Boole­schen Wert (allgemeines Predicate) oder eine Dezimalzahl ergibt, die eine Item­nummer der Ausgangssequenz bezeichnet (numerisches Predicate). Dieser Aus­druck wird in eckige Klammern gestellt. Es dürfen beliebig viele Predicate-Ausdrücke aufeinander folgen:

achsenschritt[predicate]*

Zwei Predicates sind nicht einfach miteinaner vertauschbar. Folgende Ausdrücke ergeben also (in der Regel!) nicht die gleiche Ergebnissequenz:

achsenschritt[a][b]

ist nicht gleichbedeutend mit

achsenschritt[b][a]

Ein Beispiel hierzu wird weiter unten gegeben.

Das allgemeine Predicate

Ein Predicate dient dazu, eine Sequenz zu filtern, indem es Items entweder behält oder verwirft. Ein allgemeines Predicate erzeugt einen Booleschen Wert, der bestimmt, ob der geprüfte Knoten der Ergebnissequenz zugeschlagen wird oder nicht:

$sequenz[bedingung]

Die Bedingung kann in Form eines Vergleichs (z.B. [@typ='warnung']) oder eines existenziellen Ausdrucks vorliegen (Prüfung auf Vorhandensein eines Knotens, z.B. [mein_element] prüft das Vorhandensein eines Kindelements mein_element).

Beispiele:

Vollständig Syntax:

Jeder in vollständiger Syntax geschriebene Achsen­schritt kann ein oder mehrere allgemeine (oder/und numerische) Predicates erhalten, die die Ergebnissequenz des jeweiligen Schritts filtern.

/descendant::bild[fn:position()=20]
wählt das zwanzigste Ele­ment bild innerhalb des Dokuments. Dieses Predicate verwendet einen Vergleichsausdruck, der die Positionsangabe des Knotens innerhalb der Aus­gangssequenz (die sich aus dem Achsenschritt ergibt) auswertet.

/child::buchliste/child::buch[fn:position()=5]/child::kapitel[fn:position()=2]
wählt das zweite Element kapitel innerhalb des fünften Elements buch, einem Kindelement des Wur­zelelements buchliste (der Ausdruck setzt am Dokumentknoten an und geht von diesem aus auf der Child-Achse zum Wurzelelement des Doku­ments, das ein Element buchliste ist).

child::abschnitt[attribute::typ="warnung"]
wählt alle Ele­mentknoten abschnitt, die ein Attribut typ mit dem Wert warnung besit­zen.

child::*[self::kapitel or self::nachwort] 
wählt alle Kind­knoten kapitel und nachwort des Kontextknotens aus.

Abgekürzte Syntax:

Jeder in abgekürzter Syntax geschriebene Achsen­schritt kann ein oder mehrere allgemeine (oder/und numerische) Predicates erhalten, die die Ergebnissequenz des jeweiligen Schritts filtern.

*[@typ]
wählt einen beliebig benannten Elementknoten aus, der Kind des Kontextknotens ist und ein Attribut typ besitzt. Das Predicate enthält also einen existenziellen Ausdruck. Über den Wert des Attributs wird keine Aussage gemacht.

buch[@isbn]
Ein Element buch, das Kind des Kontextknotens ist, muss ein Attribut isbn besitzen. Dessen tatsächlicher Attributwert ist gleich­gültig.

buch[autor='James Joyce']
Ein Element buch, das Kind des Kon­textknotens ist, muss ein Kindelement autor besitzen, dessen Stringwert 'James Joyce' ist.

Das numerische Predicate

Ein numerisches Predicate prüft, ob die Position des Items in der Eingangsse­quenz dem numerischen Wert innerhalb des Predicates entspricht. Der Wert des numerischen Predicates muss stets eine Ganzzahl sein.

Beispiel:

Dieses numerische Predicate wählt das fünfte Item der Sequenz aus und verwirft die übrigen:

$sequenz[5]

Jedes numerische Predicate kann auch in Form eines allgemeinen Predicates geschrieben werden, sodass es genau genommen lediglich eine Abkürzung dar­stellt. So ist

$sequenz[2]

dasselbe wie

$sequenz[fn:position() = 2]

Mehrere aufeinander folgende Predicates

Jeder Achsenschritt kann mittels beliebig vieler Predicates gefiltert werden. Ob es sich bei ihnen um allgemeine oder numerische Predicates handelt, ist gleich­gültig. Die Reihenfolge, in der die Predicates auftreten, ist hingegen von Bedeu­tung:

abschnitt[@typ="warnung"][5]
wählt das fünfte Kindelement des Kontextknotens mit Bezeichner abschnitt, das ein Attribut typ mit Wert 'warnung' besitzt (also das fünfte derjenigen Ele­mente, die ein Attribut dieses Wertes haben).

abschnitt[5][@typ="warnung"]
wählt das fünfte Kindelement abschnitt, wenn dieses ein Attribut typ mit Wert 'warnung' besitzt.

Achtung – Die Reihenfolge der Predicates ist relevant:
Vergleichen Sie die bei­den vorangehenden Beispiele, so wird deutlich, dass die Reihenfolge der Predicates relevant ist. Die Filterung erfolgt von links nach rechts, daher bedeutet es einen Unterschied, ob Sie abschnitt[@typ= "warnung"][5] oder abschnitt[5][@typ="warnung"] schreiben.
Im ersten Fall werden erst alle Element abschnitt mit entsprechendem Atributwert gewählt und von die­sen das fünfte, im zweiten wird das fünfte Element abschnitt getestet, ob es ein Attribut mit dem entsprechenden Wert besitzt. Die Ergebnissequenz kann zufälligerweise gleich sein, der Regelfall ist dies jedoch nicht.

   

<< zurück vor >>
Tipp der data2type-Redaktion:
Zum Thema XPath bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Galileo Press, Rheinwerkallee 4, 53227 Bonn