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:
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
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.
sum benötigt als Argument
eine Liste und gibt dafür die Summe der Elemente der Liste zurück.
count benötigt als Argument
eine Liste und gibt dafür die Anzahl der Elemente der Liste zurück.
avg benötigt als Argument
eine Liste und gibt dafür den Durchschnitt der Elemente der Liste
zurück.
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.
contains, um zu sehen,
ob eine Zeichenkette in einer anderen Zeichenkette vorkommt (so ist etwa
contains("Beethoven", "Beet")
wahr, aber contains("Beethoven", "Beat")
falsch),
substring, um aus einer
Zeichenkette eine andere Zeichenkette zu extrahieren (durch Angabe
der Startposition und der Länge, zB ergibt
substring("Wertzeichen", 3, 5)
die Kette "rtzei"),
substring-after, um in einer
Zeichenkette den Rest herauszusuchen, der hinter der gegeben
Zeichenkette steht (etwa ist
substring-after("abcdef", "c")
genau "def",
substring-before, um in einer
Zeichenkette den Rest herauszusuchen, der vor der gegeben
Zeichenkette steht (etwa ist
substring-before("abcdef", "c")
genau
"ab".
Ähnliche Funktionen gibt es auch für Listen.
Vorige Seite
Hauptseite
Nächste Seite