Knoten filtern

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie müssen Knoten auf der Grundlage der Daten auswählen, die sie enthalten, anstatt aufgrund der Namen oder der Position oder zusätzlich zu den Namen oder der Position.

Lösung

Viele der Minirezepte unter Rezept Achsen effektiv benutzen verwendeten Prädikate, um Knoten zu filtern. Allerdings beruhten diese Prädikate streng auf der Position des Knotens oder Knotennamens. Hier betrachten wir eine Reihe von Prädikaten, die auf der Grundlage des Dateninhalts filtern. In diesen Beispielen benutzen wir einen einfachen Kindelementpfad X vor jedem Prädikat. Man könnte aber natürlich ebenso jeden Pfadausdruck für X einsetzen, einschließlich derer aus dem Rezept Achsen effektiv benutzen.

Anmerkung:
In den folgenden Beispielen setzen wir die XPath-2.0-Vergleichsoperatoren (eq, ne, lt, le, gt und ge) anstelle der Operatoren (=, !=, <, <=, > und >=) ein! Dies tun wir, da bei einem Vergleich atomarer Werte die neuen Operatoren bevorzugt werden. In XPath 1.0 haben Sie nur die letztgenannten Operatoren, führen Sie also die entsprechende Ersetzung durch. Die neuen Operatoren wurden in XPath 2.0 eingeführt, weil sie eine einfachere Semantik haben und infolge dessen wahrscheinlich effizienter sind. Die Komplexität der alten Operatoren macht sich bemerkbar, wenn man Fälle betrachtet, bei denen auf beiden Seiten des Vergleichs eine Sequenz steht. Das Rezept Knotenvergleiche verwenden geht näher auf dieses Thema ein.

Eine weitere Bemerkung gilt allen, die in XPath 2.0 arbeiten, weil diese Version Typinformationen berücksichtigt, wenn ein Schema zur Verfügung steht. Dies könnte dazu führen, dass einige der unten gezeigten Ausdrücke Typfehler aufweisen. Beispielsweise ist X[@a = 10] nicht das Gleiche wie X[@a = '10'], wenn das Attribut vom Typ Integer ist. Wir nehmen hier an, dass es kein Schema gibt und alle atomaren Werte daher vom Typ untypedAtomic sind. Mehr Informationen über dieses Thema können Sie in den Rezepten Das erweiterte Typsystem von XPath 2.0 bewältigen und Das erweiterte Typsystem von XPath 2.0 ausnutzen finden.

(: Auswählen der X-Kindelemente, die ein Attribut namens a haben. :)

X[@a]

(: Auswählen der X-Kinder, die wenigstens ein Attribut haben. :)

X[@*]

(: Auswählen der X-Kinder, die wenigstens drei Attribute haben. :)

X[count(@*) > 2]

(: Auswählen der X-Kinder, deren Attribute in der Summe einen Wert kleiner als 7 haben. :)

X[sum(foreach $a in @* return number($a)) < 7] (: In XSLT 1.0 benutzen Sie sum(@*) &lt; 7 :)

(: Auswählen von X-Kindern, die keine Attribute namens a haben. :)

X[not(@a)]

(: Auswählen von X-Kindern, die keine Attribute haben. :)

X[not(@*)]

(: Auswählen von X-Kindern, die ein Attribut namens a mit dem Wert '10' haben. :)

X[@a eq '10']

(: Auswählen von X-Kindern, die ein Kind namens Z mit dem Wert '10' haben. :)

X[Z eq '10']

(: Auswählen von X-Kindern, die ein Kind namens Z mit einem Wert ungleich '10' haben. :)

X[Z ne '10']

(: Auswählen von X-Kindern, wenn diese wenigstens einen Textknoten als Kind haben. :)

X[text( )]

(: Auswählen von X-Kindern, wenn sie einen Textknoten mit wenigstens einem Zeichen haben, das kein Leerraum ist. :)

X[text( )[normalize-space(.)]]

(: Auswählen von X-Kindern, wenn sie einen beliebigen Kindknoten haben. :)

X[node( )]

(: Auswählen von X-Kindern, wenn sie einen Kommentarknoten enthalten. :)

X[comment( )]

(: Auswählen von X-Kindern, wenn sie ein @a haben, dessen numerischer Wert kleiner als 10 ist. Dieser Ausdruck funktioniert in XPath 1.0 und 2.0 gleichermaßen, unabhängig davon, ob @a ein String oder ein numerischer Typ ist. :)

X[number(@a) < 10]

(: Auswählen von X, wenn es wenigstens einen vorhergehenden Geschwisterknoten namens Z mit einem Attribut y hat, das ungleich 10 ist. :)

X[preceding-sibling::Z/@y ne '10']

(: Auswählen von X-Kindern, deren Stringwert aus einem einzigen Leerzeichen besteht. :)

X[. = ' ']

(: Eine seltsame Methode, um eine leere Sequenz zu erhalten! :)

X[false( )]

(: Identisch mit X. :)

X[true( )]

(: X-Elemente mit genau 5 Kindelementen. :)

X[count(*) eq 5]

(: X-Elemente mit genau 5 Kindknoten (einschließlich Element-, Text-, Kommentar- und PI-Knoten, aber ohne Attributknoten). :)

X[count(node( )) eq 5]

(: X-Elemente mit genau 5 Knoten beliebiger Art. :)

X[count(@* | node( )) eq 5]

(: Das erste X-Kind, vorausgesetzt, es hat den Wert 'beliebiger Text'; ansonsten leer. :)

X[1][. eq 'beliebiger Text']

(: Auswählen aller X-Kinder mit dem Wert 'beliebiger Text' und Rückgabe des ersten oder leer, falls es ein solches Kind nicht gibt. Mit einfachen Worten: das erste X-Kind, das den Stringwert 'beliebiger Text' hat. :)

X[. eq 'beliebiger Text'][1]

Diskussion

Wie beim Rezept Achsen effektiv benutzen ist es unmöglich, vollständig alle interessanten Permutationen von Filterprädikaten zu behandeln. Wenn Sie jedoch die Themen verstanden haben, die oben beispielhaft dargestellt wurden, sollten Sie in der Lage sein, praktisch jeden gewünschten Filterausdruck zu entwickeln. Bedenken Sie außerdem, dass man mit Hilfe der logischen Operatoren and, or und der Funktion not( ) komplexere Bedingungen erzeugen kann.

number(@a) > 5 and X[number(@a) < 10]

Wenn Sie bei komplexen Pfadausdrücken Prädikate einsetzen, müssen Sie die Wirkungsweise von Klammern verstehen.

(: Auswählen des ersten Y-Kindes jedes X-Kindes des Kontextknotens. Dieser Ausdruck kann eine Sequenz aus mehr als einem Y zum Ergebnis haben. :)

X/Y[1]

(: Auswählen der Sequenz der Knoten X/Y, dann wird der erste genommen. Dieser Ausdruck kann höchstens ein Y auswählen. :)

(X/Y)[1]

Ein Informatiker würde sagen, dass der Bedingungsoperator [] enger bindet als der Pfadoperator /.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" 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.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de