Vergleichsausdrücke

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

Mittels Vergleichsausdrücken können die Werte zweier Teilausdrücke eines zusammengesetzten Ausdrucks verglichen werden. Das Ergebnis eines Ver­gleichsausdrucks ist ein Boolescher Wert: true, wenn der Vergleich erfüllt ist, false, wenn der Vergleich fehlschlägt.

Insgesamt unterscheidet man in XPath 2.0 vier verschiedene Typen von Ver­gleichen mit unterschiedlichen Sätzen von Operatoren: Wertvergleiche, Allge­meine Vergleiche, Knotenvergleiche und Vergleiche anhand der Dokumentrei­henfolge.

Hier eine kurze Auflistung der jeweils verwendeten Operatorsymbole:

  • Vergleich von Einzelwerten: eq | ne | lt | le | gt | ge
  • Allgemeine Vergleiche: = | != | < | <= | > | >=
  • Vergleiche zwischen Knoten: is | isnot
  • Vergleich der Position im Dokument: << | >>

Vergleich von Einzelwerten

Operatoren: eq, ne, lt, le, gt, ge

Diese Operatoren dienen ausdrücklich dem Vergleich von atomaren Einzelwerten. Zum Vergleich komplexer Werte bzw. Sequenzen existieren eigene Operatorsymbole (siehe unten). (Anmerkung: Obwohl beispielsweise hinter den Operatorsymbolen »eq« und »=« die gleiche vordefinierte Operatorfunktion arbeitet (im Sinne einer Überladung), ist das Ergebnis eines Einzelwertvergleichs mit »eq« unter Umständen ein anderes als bei einem allgemeinen Vergleich mit »=«.)

Um einen Einzelwertvergleich vorzunehmen, werden die beiden zu verglei­chenden Operanden zunächst atomisiert – dies geschieht analog zur Anwen­dung der Funktion fn:data(). Falls sie dann in Form des Typs xdt:untypedA­tomic vorliegen, werden sie in Stringwerte vom Typ xs:string umgewandelt, andernfalls bleibt der Wert unverändert. Schlägt die Atomisierung fehl, so wird eine Fehlermeldung erzeugt.

Anschließend wird der eigentliche Vergleich durchgeführt. Das Ergebnis ist ein Boolescher Wert – true oder false, je nachdem, ob die Vergleichsbedingung erfüllt ist oder nicht.

  • eq: 3 eq 3 ergibt true
  • ne: 3 ne 3 ergibt false

Die Verwendung des eq-Operators ist mit Vorsicht zu genießen: Der folgende Vergleich ergibt nur dann true, wenn der Ausdruck $buch ein einzelnes Kind­­element autor besitzt (nicht mehrere!) und dessen Stringwert gleich »James Joyce« ist:

$buch/autor eq "James Joyce"

Existiert zwar nur ein einzelnes autor-Element, ist dessen Wert jedoch ein anderer, so ergibt der Vergleich den Wert false. Sobald jedoch mehrere Kind­­elemente autor existieren, endet der Vergleich mit einer Fehlermeldung.

Achtung – Keine implizite Typumwandlung in XPath 2.0:
In XPath 1.0 war es üblich, dass eine Typumwandlung im Rahmen eines Vergleichs implizit vor­genommen wurde. Dies ist in XPath 2.0 nicht der Fall.
So erzeugt der Vergleich 3 eq "3" einen Fehler und müsste mit expliziter Typumwandlung eines der Operanden als 3 eq fn:number("3") oder fn:string(3) eq "3" geschrieben werden.

Rückblick auf XPath 1.0

XPath 1.0 kennt keine Operatoren, die unmit­telbar Einzelwerte miteinander vergleichen. Statt dessen werden dort die allge­meinen Vergleichsoperatoren verwendet, die allerdings ausschließlich numeri­sche Werte miteinander vergleichen können.

Allgemeine Vergleichsoperationen

Operatoren: =, !=, <, <=, >, >=

Allgemeine Vergleiche können mit belie­bigen Operanden vorgenommen werden. Der Vergleich von Sequenzen arbei­tet dabei auf der Grundlage des Quantitäts­operators some – die Länge der ver­glichenen Sequenzen spielt dabei keine Rolle. So lange nicht unmittelbar ein Fehler auftritt, gibt ein allgemeiner Vergleich daher ungeachtet der Eigenschaf­ten der Operanden stets true oder false zurück.

Handelt es sich bei den verglichenen Operanden um nicht atomare Werte, so werden sie zunächst atomisiert (wie durch fn:data()), und die so entstande­nen Sequenzen werden verglichen, ob ein beliebiges Itempaar den Vergleich erfüllt.

Liegen die Operanden nun somit als Folgen atomarer Werte vor, so werden diese entsprechend des Einzelwertvergleichs mittels der Operatoren eq, ne, lt, le, gt, oder ge verglichen, je nachdem, ob der Operator des zugrunde liegen­den allgemeinen Vergleichs =, !=, <, <=, > oder >= war.

Die Bedingungen des allgemeinen Vergleichs werden als erfüllt betrachtet, wenn der entsprechende Einzelwertvergleich der atomisierten Werte erfüllt ist.

Der folgende allgemeine Vergleich ist daher erfüllt, wenn der Ausdruck $buch eine beliebige Zahl von Kindelementen autor hat, von denen eines den String­wert »James Joyce« besitzt (dies entspricht der »existenziellen Quantifizierung« mit some – siehe unten.):

$buch/autor = "James Joyce" 

Hinweis – Escaping in XPath-Ausdrücken
Innerhalb von XML-Dokumenten, also auch in XSLT-Stylesheets, müssen die XPath-Ausdrücke den Regeln für Sonderzeichen folgen. Der Ver­gleichsoperator < muss daher als &lt; umschrieben werden (auch für <=). Normalerweise wird man ebenfalls den Operator > maskieren, obwohl dies nicht unbedingt erforderlich ist.

Rückblick auf XPath 1.0

In XPath 1.0 wird beim Vergleich zweier Werte eine implizite Typumwandlung vorgenommen. Ein Vergleich wird anschlie­ßend anhand eines allgemeinen Vergleichsoperators durchgeführt. Relational (d.h. nach Eigenschaften wie größer, kleiner etc.) können nur Zahlenwerte miteinander verglichen werden bzw. solche Werte, die in einen Zahlenwert umwandelbar sind – ein Stringvergleich (außer auf Gleichheit) ist in XPath 1.0 nicht möglich.

Vergleiche zwischen Knoten

Operatoren:  is, isnot

Der Knotenvergleich zielt auf die Identität oder Nicht-Identität zweier Knoten ab, nicht auf deren Wertgleichheit. Letztere kann mittels eines allgemeinen Vergleichs festgestellt werden. Ob es sich bei den verglichenen Knoten jedoch um ein und denselben Knoten handelt, ist mit einem allgemeinen Vergleich nicht eindeutig feststellbar.

Um einen Knotenvergleich vornehmen zu können, müssen die beteiligten Operanden zwingend aus je einem einzelnen Knoten bestehen. Ist dies nicht der Fall, wird ein Typfehler gemeldet. Die leere Sequenz für einen oder beide Operan­den erzeugt hingegen keinen Typfehler – der Rückgabewert des versuchten Vergleiches wird in diesem Fall jedoch ebenfalls eine leere Sequenz sein und kein Boole­scher Wert. (Allerdings kann die zurückgegebene leere Sequenz in diesem Kontext letztlich als false gewertet werden.)

Handelt es sich bei den beiden Operanden um Knoten, so ist ein Vergleich mit­tels des is-Operators dann true, wenn beide verglichenen Knoten miteinan­der identisch sind, mit anderen Worten, wenn es sich um ein- und denselben Knoten handelt. Der Vergleich über isnot ist dagegen true, wenn die Knoten miteinander nicht identisch sind.

Der folgende Vergleich ist dann true, wenn die beiden verglichenen Ausdrü­cke denselben Knoten bezeichnen:

//buch[isbn="3-518-11100-0"] is //buch[titel="Ulysses"]

Den formalen Hintergrund dieser Operatoren bildet die Operatorfunktion op:node-equal(), die jedoch vom User selbst nicht direkt aufrufbar ist. Der Vergleich a is b entspricht also op:node-identical(a, b), der Vergleich a isnot b wiederum not(op:node-identical(a, b)).

Rückblick auf XPath 1.0

Ein direkter Vergleich auf Knotenidentität ist in XPath 1.0 nicht vorgesehen. Es ist jedoch eine Hilfskonstruktion mit der count()-Funktion möglich. Soll ein Knoten $a mit einem Knoten $b verglichen werden, so ergibt folgender Test true, wenn beide Knoten identisch sind: count($a | $b) = 1

Vergleich der Position im Dokument

Operatoren: <<, >>

Mittels der Operatoren << und >> können zwei Kno­ten auf ihre Position zueinander in Bezug auf die Dokumentreihenfolge vergli­chen werden. Die Operatoren arbeiten mit zwei Operanden, bei denen es sich zwingend um Knoten handeln muss. Resultiert einer der als Operanden die­nenden Ausdrücke nicht in einem einzelnen Knoten, so wird dies als Typfehler gewertet. Keinen Typfehler bewirkt die leere Sequenz für einen oder beide Operanden. In diesem Fall gibt der Vergleich ebenfalls eine leere Sequenz zurück.

Der Vergleich zweier Knoten mit dem Operator << ergibt dann true, wenn der Knoten, der durch den linken Operator repräsentiert wird, dem Vergleichskno­ten in Dokumentreihenfolge vorangeht, ansonsten false.

Analog ergibt ein Vergleich zweier Knoten mittels >> dann und nur dann true, wenn der linke Operand dem Vergleichsknoten der rechten Operanden in Dokumentreihenfolge folgt.

Die Operatorsymbole << und >> arbeiten wie üblich auf Grundlage von inter­nen Operatorfunktionen, die selbst aber nicht unmittelbar aufrufbar sind. Hier­bei entspricht der Ausdruck a << b dem Funktionsaufruf op:node-before(a, b) und der Ausdruck a >> b dem Funktionsaufruf op:node-after(a, b).

Rückblick auf XPath 1.0

In XPath 1.0 existieren keine Operatoren, die Knotenpositionen zueinander bewerten können. Es sind allerdings Hilfskonst­ruktionen mit Preceding- und Following-Achse möglich.

   

<< 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