Vorige Seite     Hauptseite     Nächste Seite


Informationsstrukturierung: Mo, 21.05.2012. XPath II. Tests.

Prädikate und Tests.

Wie schon erwähnt, ist XSLT nur für die Ausführung der Transformation zuständig. Für das Rechnen ist XPath zuständig. XPath rechnet mit Zahlen, Zeichenketten, Datumsangaben, Booleschen Werten, und eben auch mit Knoten. Das Attribut select has als Wert einen XPath Ausdruck, der einen Test ergibt, zum Beispiel einen Knotentest. XPath berechnet aus diesem Test eine Liste von Knoten und gibt diese an XSLT zurück. In dieser Vorlesung befasse ich mich ausführlicher mit den Tests. Dazu muss ich die Aussagen über Pfadausdrücke noch einmal beleuchten. Ein Einzelschritt hat die Syntax pfad::test. Faktisch hat sich dabei ergeben, dass sowohl pfad wie auch test relational sind und deswegen eine Liste auswerfen. So ist descendant::name die Aufforderung, zunächst die Nachfahren abzuprüfen. name wirft die Knoten mit Tag name aus. Gekoppelt mit dem Nachfahren-Schritt bekommen wir also eine Liste. Wiederum sollte man sich die Semantik von :: als Relationale Verkettung (∘) vorstellen. Hinzu kommen jetzt noch die sogenannten Filterausdrücke. Die volle Syntax ist mithin:
schritt::prädikat [filter1] [filter2]⋯ [filtern]
Der Ausdruck filteri ist vom Typ Boolean oder Zahl. Das bedeutet, dass er eine Bedingung an Knoten angibt. Die Semantik der eckigen Klammern, also [⋯], ist die des Schnitts, genauer: die Liste wird geschnitten mit der Knotenmenge, die den Ausdruck in den Klammern erfüllt. Damit ist nun gesagt, was Filter sind. Ich werde nun einige solche Filterausdrücke vorstellen.

Tags

Eine häufige Verwendung von Tests ist sicher die, dass man den Wert eines Attributs abfragen will. Dies geht wie folgt:
child::node()[@att = wert]
Dies kann man auch wie folgt abkürzen:
*[@att = wert]
Der Stern wird hier aus syntaktischen Gründen gebraucht. Dieser ist wie bei Unix üblich ein Joker: er matcht jede Zeichenkette.

Position

Wie schon gesagt, kann der Testausdruck auch ein Zahlausdruck zahl sein. In diesem Fall wird dieser Ausdruck als der folgende Test interpretiert
position() = zahl
Dies benutzt also die Position. So ist also
following-sibling::node()[23]
dasselbe wie
following-sibling::node()[position() = 23]
und bedeutet, dass wir unter den folgenden Schwesterknoten den 23ten nimmt. Natürlich kann man auch andere Knoten auswählen.
following-sibling::node()[position() < 23]
following-sibling::node()[position() != 23]
following-sibling::node()[position() != last()]
Diese wählen alle Knoten vor dem 23ten, alle außer dem 23ten, und alle außer dem letzten aus. Der letzte Ausdruck verwendet die Funktion last(), welche wahr ist, wenn die Position die letzte in der Liste ist. (Man überlege sich, ob es eine Funktion first() geben muss, oder ob diese im Prinzip überflüssig ist.) Es gibt auch die Möglichkeit zu testen, ob ein Knoten vor einem anderen Knoten ist (mittels <<.)

Boolesche Ausdrücke

Es gibt die üblichen drei Ausdrücke: not, and und or. Wie üblich bindet Konjunktion stärker als Disjunktion.

Arithmetik

XPath erlaubt auch, zu rechnen. Die Grundfunktionen sind dabei relativ eingeschränkt. Wir haben die Grundrechenarten, also +, -, * und div. Ferner gibt es idiv (Division von ganzen Zahlen). Dazu kommen die numerischen Vergleiche. Interessant in diesem Zusammenhang ist die Rundung. XPath stellt zwei Funktionen zur Verfügung: round, welche eine ganze Zahl rundet, sowie round-half-to-even. Diese Funktion ist wie folgt. Das erste Argument ist die zu rundende Zahl, das zweite gibt die Nachkommastellen an. Wir können mit dieser Funktion zum Beispiel auf 2 oder 3 oder eine andere Zahl von Nachkommastellen runden. Dabei gibt es aber eine Spezialität: anders als bei der normalen Rundung wird im Fall, dass die zu rundende Zahl genau auf der Hälfte liegt, nicht automatisch nach oben gerundet. Sondern es wird zu derjenigen Zahl gerundet, bei der die letzte Ziffer gerade ist. So ist round-half-to-even(3.1478,3) deswegen 3.148, aber round-half-to-even(3.1468,3) ist 3.146. Diese Funktion hat den Vorteil, dass sie die Statistik nicht verschiebt (insbesondere den Mittelwert). Die Standardrundung, so die Idee, wird nur dann benötigt, wenn man eine Ausgabe haben will. Ansonsten soll man der anderen Funktion den Vorzug geben. Es gibt ein paar nützliche arithmetische Funktionen auf Listen. Es ist also avg(t) dasselbe wie sum(t)/count(t). Damit lassen sich schon jetzt mächtige Anwendungen schreiben. Eine besonders beliebte ist das Scheckbuch. Hier sind die Einträge stets irgendwelche Kontobewegungen, und wir können mit dem Befehl sum jeweils Bilanz machen. Über die Listenfilter können wir auch aus den Kontobewegungen bestimmte Element herausfiltern und nur diese zusammenrechnen. Zum Beispiel
<xsl:value-of select="avg(/kurs/student[1 to 10]/note)">
Dies bildet den Durchschnitt der Noten bei den ersten zehn Studenten. Zusätzlich gibt es noch die Rekursion, die ich allerdings erst später besprechen werde. Zusammen mit rekursiv definierten Funktionen kann man letztlich mit Hilfe von XSLT Tabellenkalkulation jeder Art vornehmen.

Zeichenkette

XPath stellt auch Funktionen zur Manipulation von Zeichenketten zur Verfügung. Ähnliche Funktionen gibt es auch für Listen.

Vorige Seite     Hauptseite     Nächste Seite