Vorige Seite     Hauptseite     Nächste Seite


Informationsstrukturierung: Mo, 11.06.2012. XPath III. Listen.

Grundlegendes.

In XPath sind Listen grundsätzlich flach. Die Listenkonkatenation wird mit einem Komma notiert. So ist 1, 2, 3 die Liste bestehend aus den Elementen 1, 2 und 3. Eine Gruppierung in (1, 2), 3 bezeichnet dieselbe Liste. Eine Liste von Listen von Zeichenketten ist also wieder eine Liste von Zeichenketten. Ein einziges Element ist identisch mit der Liste der Länge 1 bestehend aus diesem Element.
Auf der einen Seite ist nun eine Liste der Länge 1 nicht unterscheidbar von dem Element, auf der anderen Seite muss man gelegentlich doch aufpassen. Die Funktion max zum Beispiel erwartet ein einziges Argument. Es ist daher unzulässig zu schreiben max(1,2,5). Die Klammern sind lediglich anwesend, um die Argumente der Funktion sichtbar zu machen. Innerhalb des Funktionsausfrufs dient nun das Komma dazu, die Argumente voneinander zu trennen. Deswegen ist es nötig, noch einmal Klammern zu setzen, damit klar ist, dass es sich nicht um drei Argumente handelt sondern um ein einziges, eine Liste:
max((1, 2, 5))
Es gibt drei Prädikate, mit denen man Listen überprüfen kann. Normalerweise benötigt man diese aber nicht (man hat ja auch noch die Funktion count, siehe weiter unten).

Erzeugen von Listen

Es gibt mehrere Arten, Listen zu erzeugen. Aus Dokumenten kann man sich mit Hilfe von Pfadausdrücken Listen von Knoten besorgen. Man kann eine Liste auch mit dem Komma hinschreiben: Katze, Hund, Maus. Dabei kann man auch Klammern verwenden:
(Katze, Hund, Maus)
Gruppierungen sind möglich aber technisch irrelevant. Für ganze Zahlen gibt es noch den Konstruktor to. Dieser hat folgende Syntax: m to n , wo m und n ganze Zahlen bezeichnen. Das Ergebnis ist die Liste aller ganzen Zahlen, aufsteigend geordnet, beginnend mit m und endend mit n. Ist n kleiner als n, so ist die Liste leer; sind die Zahlen gleich, so erhält man eine Liste mit einer einzigen Zahl.
1 to 5 = 1, 2, 3, 4, 5
An dieser Stelle sei noch erwähnt, dass es in XPath Variable gibt. Jede Zeichenkette kann als Variable gelten. Sie muss nur obligatorisch mit $ beginnen. So ist zum Beispiel $wert eine Variable. Dann kann man schreiben
1 to $wert
Es gibt zahlreiche Funktionen auf Listen, von denen ich ein paar vorstellen möchte. Michael Kay bespricht eine interessante Möglichkeit, sich den Listenplatz anzuzeigen. XSLT stellt dazu eine Funktion namens xsl:number bereit. So können wir uns über den Befehl <xsl:number/> unmittelbar anzeigen lassen, der wievielte Teilnehmerknoten wir sind. Alternativ dazu kann man schreiben
count(preceding-sibling::teilnehmer)+1
Was man hier tut, ist, sich die Liste aller vorangegangenen Knoten zu besorgen, daraus alle teilnehmer -Knoten auszusuchen (was man nicht muss, wenn man sicher ist, dass es nur solche gibt, also könnte wir da auch node() schreiben) und schließlich 1 hinzuzufügen, weil wir ja schon an der nächsten Position stehen.

Iteratoren

XPath 2.0 erlaubt, eine beliebige Funktion auf die Element einer Liste anzuwenden. Ist F eine Funktion und L = l1, ⋯, ln eine Liste, so bekommt man mit
for $i in L return F($i)
die Liste
F(l1), F(l2), ⋯, F(ln),
Hier ist ein Beispiel.
for $i in 1 to 5 return $i * $i
Dies ergibt die Liste
1, 4, 9, 16, 25
Die anzuwendende Funktion kann irgendwas sein, sie darf auch Listen auswerfen. In diesem Fall werden aber die Listen aneinandergereiht, und es entsteht eine große Liste:
for $i in 0 to 4 return 1 to $i
Dies erzeugt folgende Liste.
1, 1, 2, 1, 2, 3, 1, 2, 3, 4
Man mache sich klar, wie das zustandegekommen ist. Für $i=0 bekommt man die leere Liste (der Ausdruck 1 to 0 ist nach dem oben Vereinbarten leer). Für $i=1 bekommt man 1, für $i=2 die Liste 1,2, und so weiter. Mit Hilfe von Klammern sieht das etwa so aus:
(), (1), (1, 2), (1, 2, 3), (1, 2, 3, 4)
Wichtig! for Ausdrücke versetzen nicht den Fokus. Dazu ein Beispiel. Wir wollen die Klausurergebnisse der Teilnehmer in eine Liste werfen. Der Fokus ist im Knoten kurs, welcher unter sich alle Teilnehmerknoten beherbergt. Das Folgende tut nicht das Gewünschte unter der Annahme, dass die klausur Knoten jeweils unter dem teilnehmer Knoten sitzen.
for $i in teilnehmer return klausur
Richtig ist vielmehr
for $i in teilnehmer return $i/klausur
Um zu verstehen, wie der Code funktioniert, noch einmal eine genaue Erklärung. Das Wort teilnehmer ist ein Pfadausdruck und wirft eine Liste von Knoten aus, etwa k1, k2,⋯, kn. Für diese wird nun der Ausdruck berechnet (Fokus ist gleichgeblieben). Hier kommt nun wieder ein Pfadausdruck, aber dieser ändert sich ständig, weil er ja von dem gewählten Knoten abhängt. Deswegen steht hier die Variable $i. Sie gibt uns den Unterknoten, dh sie erlaubt uns, den Fokus zu versetzen. Man sehe sich genau den Gebrauch von Variable in Pfadausdrücken an.

Quantoren

XPath erlaubt auch, zu quantifizieren. Die Syntax ist
some $i in L satisfies B
B ist ein Ausdruck, der für die Listenelemente jeweils einen Wahrheitswert ergeben muss. Hierbei wird $i in B vorkommen, muss es aber nicht. Zum Beispie können wir herausfinden, ob jemand an der Klausur nicht teilgenommen hat:
some $i in teilnehmer satisfies $i/klausur eq ''
Es wäre in diesem Fall auch möglich, Folgendes zu nehmen:
teilnehmer[klausur = '']
Dies würde uns eine Liste geben. Diese kann man aber in einen Wahrheitswert umrechnen: die leere Liste ist falsch, alles andere ist wahr. Das kann man zum Beispiel mit der Funktion exists (siehe unten). Damit kommen wir auf das gleiche Ergebnis. Ebenso gibt es noch den Allquantor
every $i in L satisfies B
Es gibt für beide Quantoren eine Kurzform. Und zwar kann man mehrere gleichartige Quantoren zusammenziehen. Anstelle von
every $i in L satisfies
  (every $j in M satisfies B)
darf man schreiben
some $i in L, $j in M satisfies B
Es gibt noch eine weitere Kurzschreibweise. Nämlich mit der Funktion exists. Diese braucht als einziges Argument eine Liste und gibt wahr aus, wenn diese Liste nicht leer ist. Es gelten die Gesetze der Logik. Es ist (∀x)χ äquivalent mit ¬(∃x)¬χ. Deswegen kann man den Allquantor wie folgt ersetzen:
not (some $i in L satisfies not (B))
Wichtig! Genau wie for versetzen die Quantoren den Fokus nicht.

Boolesche Verbindung

An dieser Stelle sollte ich noch einmal auf die booleschen Junktoren zu sprechen kommen. XPath kennt außer den Quantoren und Iteratoren noch die Junktoren if⋯then (mit optionalem else), and und or. Diese haben die übliche Bindungsstärke: and bindet stärker als or. Zu den Ausdrücken, die booleschwertig sind gehören numerische Vergleiche, Knotenvergleiche (zB Abfragen, ob der Wert eines Knotens eine bestimmte Zahl ist) und so weiter. Pfadausdrücke sind jedoch von anderer Natur! Ihr Wert ist ja eine Liste von Knoten, deswegen sind sie nicht als boolesche Werte zu betrachten. Hier muss man stattdessen die folgenden Operatoren wählen:

Vorige Seite     Hauptseite     Nächste Seite