Sequenzausdrücke

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

Neben der üblichen Erzeugung von Sequenzen durch XPath-Ausdrücken bietet XPath 2.0 die Möglichkeit, beliebige Sequenzen mit Hilfe eines entsprechenden Konstruktors (Sequenzausdruck) als Literal zu erzeugen. Die Prüfung der Ergebnissequenz eines Ausdrucks auf eine gewünschte Zusammensetzung wird mittels so genannter Sequenztypen und entsprechender Operatoren gewähr­leistet.

Erzeugung von Sequenzen

Operatoren: , (Komma), to

Zur unmittelbaren Erzeugung von Sequen­zen dienen in XPath zwei Operatoren:

  • der Kommaoperator (,), der beliebige XPath-Ausdrücke in Sequenzen gruppiert
  • der Bereichsoperator to, der Sequenzen aus lückenlosen Ganzzahlenfolgen durch Angabe der oberen und unteren Grenze der Folge generiert

Der Kommaoperator

Die einfachste Methode, eine Sequenz zu erzeugen, ist der Einsatz des Kommaoperators. Hierfür werden alle auszuwertenden Operanden durch Kommas getrennt in runde Klammern gestellt.

Jeder Operand wird als Einzelausdruck betrachtet. Diese Ausdrücke werden in der im Sequenzausdruck vorgegebenen Reihenfolge ausgewertet. Die so entste­hende Kette aus Items entspricht der Ergebnissequenz:

(1, 2, 3, 4, 5)

erzeugt eine Sequenz aus den Zahlen 1, 2, 3, 4, und 5.

Da in diesem Fall Zahlen, also atomare Werte übergeben wurden, müssen die Operanden nicht ausgewertet werden. Sie finden sich unverändert in der Ergebnissequenz wieder.

Der Kommaoperator hat in XPath die niedrigste Priorität, d.h. durch ihn getrennte Ausdrücke können sich aus anderen, durch XPath-Operatoren höhe­rer Priorität (also alle anderen) verknüpften Unterausdrücken zusammenset­zen.

Achtung – Kommaoperator wird nicht als Toplevel-Operator eingesetzt:
Üblicherweise tritt der Kommaoperator nicht als Toplevel-Opera­tor auf, sondern nur bei der Verküpfung von Ausdrücken, die im Inneren einer runden Klammer stehen.

Einfaches Beispiel:

(1, 2 + 3, 3) ergibt die Folge 1 5 3.

Die runden Klammern dienen als Begrenzer des Sequenzausdrucks. Sie müssen gesetzt werden, wenn der Ausdruck in einem Kontext verwendet wird, der einen einzelnen XPath-Ausdruck erfordert, und der Kommaoperator benutzt wird. Dies ist beispielsweise in Funktionsaufrufen der Fall, aber auch in Attri­buten von XSLT-Instruktionen, die einen XPath-Ausdruck enthalten. Formal betrachtet ist also der Ausdruck (1, 2, 3, 4, 5) nicht die eigentliche Sequenz, sondern erzeugt sie.

Deutlicher wird dies, wenn statt atomarer Werte – wie im vorangestellten Beispiel – ein Knotentest verwendet wird: Der Ausdruck (test) erzeugt eine Sequenz aus allen Elementknoten <test>, die Kindknoten des aktuellen Kno­tens sind. Die Ergebnissequenz ist in Dokumentreihenfolge geordnet.

Im Gegensatz zu einem Nodeset in XPath 1.0 können in einer Node-Sequenz auch Knoten doppelt erscheinen. So erzeugt der Ausdruck (test, test) eine Sequenz, die alle <test>-Children des aktuellen Knotens zweimal enthält, ent­sprechend zweier identischer, aneinander gehängter Sequenzen, wie sie durch den Ausdruck (test) erzeugt werden.

Eine »Verschachtelung« von Sequenzen ist nicht möglich. Eine Sequenz kann also selbst nicht als Item einer ande­ren Sequenz fungieren. Wird durch Zusammenfassung zweier oder mehr Eingabesequenzen eine neue Sequenz erzeugt, so entspricht die Zahl der Items der Ergebnissequenz also stets der Gesamtzahl der Items aller Eingabesequenzen.

Beispiel:

Ist $seq1 der Sequenzausdruck (1, 2, 3) und $seq2 der Sequenzausdruck ('a', 'b', 'c'), so ergibt der Sequenzausdruck ($seq1, $seq2) nicht etwa eine Ergebnissequenz aus zwei »Sequenzitems«, sondern eine Sequenz aus sechs Items in Form der Folge 1, 2, 3, 'a', 'b' und 'c'.

Dies bedeutet auch, dass die Ausdrücke ((1, 2, 3), ('a', 'b', 'c')) und (1, 2, 3, 'a', 'b', 'c') identisch sind.

Der Bereichsoperator 'to' in Integersequenzen

Soll eine Sequenz aus Ganzzahlen erzeugt werden, die aus einer fortlaufenden Zahlenreihe besteht, so kann anstelle einer Auflistung der Einzelwerte eine RangeExpr (Bereichsausdruck) treten. Hierfür wird der to-Operator eingesetzt:

Der Ausdruck (1 to 5) ergibt die Integersequenz 1, 2, 3, 4, 5.

Eine so gewonnene, fortlaufende Sequenz kann mittels eines Predicates gefiltert werden, um beliebige andere regelmäßige Zahlenreihen zu erzeugen. Dieser Ausdruck gibt eine Folge aus durch 5 teilbaren Zahlen zurück:

(1 to 50)[. mod 5 eq 0]

Man erhält die Reihe 5, 10, 15, 20, 25, 30, 35, 40, 45, 50. Ausgefiltert werden dieje­nigen Zahlen der Primärreihe, deren »Modulo 5« ungleich 0 ist, die also nicht ohne Rest durch 5 teilbar sind.

Eine andere Anwendungmöglichkeit von Bereichsausdrücken ist innerhalb von for-Expressions. Will man beispielsweise die ersten fünf Knoten einer Node­sequenz $meine_sequenz verarbeiten, so kann einfach geschrieben werden:

for $i in 1 to 
    return ($meine_sequenz)[$i]

Hierbei nimmt die temporäre Variable $i nacheinander die Werte 1 bis 5 an. und filtert die Eingabesequenz durch ein entsprechendes numerisches Predicate.

Sequenzenbeschreibung: Sequenztypen

Im Laufe einer Verarbeitung kann die Prüfung der Zusammensetzung einer anstehenden Sequenz von Interesse sein. Diese Zusammensetzung der Sequenz aus Knoten bzw. atomaren Werten ist daher in XPath 2.0 beliebig genau formu­lierbar und wird als Sequenztyp (Sequence Type) bezeichnet. Die Prüfung einer Sequenz gegen einen Sequenztyp nennt man Sequence Type Matching.

XSLT verwendet den Sequenztyp in Zusammenhang mit dem as-Attribut in verschiedenen Instruktionen, um die Zusammensetzung einer zu verarbeiten­den Sequenz genau zu reglementieren.

Achtung – Laufzeitfehler bei Verstoß gegen Sequenztyp:
Entspricht die Ergebnissequenz der XSLT-Instruktion vom Typ (Zusammensetzung, Quantität, Schematypen etc.) nicht den durch die Sequenzenbeschreibung in ihrem as-Attribut angegebenen Bedingungen, so wird dies als Laufzeitfehler gewertet. Dies unter der Annahme, dass eine weitere Verarbeitung wegen fehlerhafter Daten ohne­hin nicht sinnvoll wäre.

Das as-Attribut ist ab XSLT 2.0 für xsl:template, xsl:variable, xsl:param sowie für die neue Instruktion xsl:function definiert. In XSLT 1.0 existiert kein vergleichbares Konzept.

Die Formulierung der Sequenztypen entspricht weitgehend den Knotentests (KindTests) in der Stepformulierung von Pfadausdrücken. Es gibt jedoch gegenüber den Knotentests einige für Sequenztypen spezifische Erweiterungen, auf die hier eingegangen werden muss.

  • Mehr Testausdrücke:
    Durch zusätzliche Testausdrücke für Sequenztypen können sowohl die leere Sequenz als auch allgemeine Items beschrieben werden:
    • empty() beschreibt die leere Sequenz
    • item() beschreibt ein Item beliebiger Art (Knoten oder atomar)
  • Beschreibung der Kardinalität:
    Einem Knotentest (der in diesem Zusammenhang besser »Itemtest« genannt wird) innerhalb eines Sequenztypausdrucks kann mittels nachgestelltem ?, + oder * ein »Kardinalitätsindikator« beigegeben werden. Auf diese Weise kann die Anzahl der Items in der beschriebenen Sequenz ausgedrückt werden
    • item()?
      Item erscheint ein- oder keinmal (»optional«)
    • item()+
      Item erscheint ein- oder mehrmals (»unbegrenzt«)
    • item()*
      Item erscheint beliebig oft oder gar nicht
    • item()
      (ohne Indikator) Item erscheint genau einmal (»obligatorisch«)

Statt des oben verwendeten item()-Tests kann, abgesehen von empty(), auch ein beliebiger anderer gültiger Testausdruck eingesetzt werden.

Darüber hinaus können in Sequenztyp-Ausdrücken alle von Location Steps her bekannten »KindTests« erscheinen, namentlich die bereits aus XPath 1.0 bekannten: node(), text(), comment() und processing-instruc­tion(). Desweiteren möglich sind die beiden, in XPath 2.0 hinzugekommenen, Testausdrücke element() und attribute(). Diese können als optionale Argumente den QName und Datentyp des bezeichneten Kno­tens (oder einen Schemapfad) übernehmen. Ein dritter, neuer Ausdruck ist der Test document-node(), das als Sequenztyp-Ausdruck eine Inhaltsbeschreibung eines eines Dokumentknotens enthalten kann.

Für die drei letztgenannten Testausdrücke gilt:

  • attribute(mein:wurzelelement/mein:bezeichner/@mein:attribut)
    bezeichnet ein Attribut mit dem QName mein:attribut, das in einem Schema innerhalb der Elementdeklarationen mein:wurzelelement und mein:bezeichner deklariert ist (die erste Elementdeklaration muss eine Toplevel-Deklaration sein, die sich im Scope befindet). Als Letztes im Pfad erscheint der Attributbezeichner mit vorangestelltem @.
  • element(mein:bezeichner, user:datentyp)
    bezeichnet ein Element mit dem QName mein:bezeichner (der QName wird beim Vergleich expan­diert) und einem userdefinierten Typ user:datentyp. Beides muss einer ent­sprechenden Schema-Deklaration gerecht werden, die sich im Scope befindet.
  • document-node(element(mein:wurzelelement))
    bezeichnet einen Dokumentknoten, der als Kindknoten das Wurzelelement mein:wurzelele­ment besitzt – dieser Inhalt wird mittels eines Elementtests beschrieben. Das Wurzelelement mein:wurzelelement muss einer Toplevel-Deklaration eines Schemas entsprechen, das sich im Scope befindet, und dem dort angegebenen Typ gerecht werden.

   

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