XQuery
Aus ProgrammingWiki
- Fred Teske(s3frtesk@stud.hs-zigr.de )
- Philipp Dvorak (s3phdvor@stud.hs-zigr.de)
Inhaltsverzeichnis |
Einstieg in XQuery
XQuery ist eine Abfragesprache für XML. Welche eine Empfehlung vom W3C ist. In diesem Kurs sollen die grundlegenden Spracheigenschaften vorgestellt werden und ein Verständnis der Syntax und Struktur von XQuery–Ausdrücken vermittelt werden.
XQuery ermöglicht:
- Auswählen von Elementen und Attributen
- Zusammenführen mehrerer XML-Dokumente
- Bearbeiten von XML-Daten
- Hinzufügen von Elementen und Attributen zu der Ergebnismengen
- Berechnungen auf Grundlage von XML-Daten
- Sortierungen der Ergebnismenge
Datenmodell
Die Basis des XQuery Datenmodells sind Sequenzen. Eine Sequenz ist die Sammlung einzelner sogenannter Items, welche mit einem Komma voneinander getrennt sind. Es sind Duplikate von Items möglich. Sequenzen funktionieren nach dem fifo–Prinzip (first in first out) d.h. das Item, das als erstes in die Sequenz eingestellt wurde, wird auch als erstes wieder ausgegeben. Die einzelnen Items können unterschiedliche Datentypen haben. XQuery bestitz eigene Datentypen für atomare Werte und von XML Schema geerbte Datentypen.
Beispiele für Sequenzen
- atomare Ganzzahl
2
- atomare Zeichenkette
'hallo'
- drei atomare Wert
(1, 2, 3)
- XML Elementknoten
<schauspieler/>
- atomare Werte und XML Elementknoten
(1, <schauspieler/>, 'hallo')
- leere Sequenz
()
Die Empfehlungen vom W3C für XQuery und XPath überschneiden sich. XPath bildet eine Untermenge von XQuery. Somit ist jeder gültige XPath-Ausdruck auch ein gültiger XQuery-Ausdruck. XQuery ist selbst keine XML-Anwendung. XQuery bestitz eine eigene Syntax.
Syntax
Bei XQuery handelt es sich um eine funktionale Sprache. Eine Abfrage wird als Ausdruck formuliert, der anschließend ausgewertet wird. Ausdrücke können beliebig verschachtelt werden. Schlüsselwörter werden klein geschrieben und sind bis auf wenige Ausnahmen nicht reserviert.
Die Abfragen werden aus mehreren Modulen zusammengestellt. Das Hauptmodul besteht aus einem optionalen Prolog und dem Teil, in dem die eigentliche Abfrage formuliert wird, der Query Body. Des Weiteren sind Bibliotheksmodule für beispielsweise benutzerdefinierte Funktionen möglich.
Der Prolog gliedert sich in zwei Teile. Im ersten Teil ist es möglich Einstellungen zu machen, welche die Verarbeitung durch den XQuery-Prozessor beeinflussen. Der zweite Teil ist für die Deklaration von Variablen und dem Import von Funktionen und Optionen vorgesehen.
Folgendes XML-Dokument soll als Basis für Beispiele und Erläuterungen dienen.
Arithmetik
XQuery besitzt eine Reihe von grundlegenden arithmetischen Operatoren zur Addition, Subtraktion, Multiplikation, Division und Modulu-Berechnung. Dabei ist der erste Schritt die Evaluierung der Operanden und erst danach die Anwendung der Operatoren. Die Ergebnisse dieser Berechnungen geben immer einen atomaren Wert zurück. Anhand der Verwendung der in ihnen benutzten Operatoren unterscheidet man in folgenden drei Kategorien:
- additive Ausdrücke
- multiplikative Ausdrücke
- unäre Ausdrücke
Additive Ausdrücke
Der Plus-Operator
Der Plus-Operator bildet die Summe aus 2 oder mehr Opperanden. Er ist durch die Funktion op:numeric-add() definiert.
Syntax: Operand1 + Operand2
Der Minus-Operator
Der Minus-Operator bildet die Differenz seiner Operanden und ist durch die Funktion op:numeric-subtract() definiert. Damit er nicht als Teil der vorangehenden Zeichenkette interpretiert werden könnte, sollte vor dem Operator ein Leerzeichen stehen.
Syntax: Operand1 - Operand2
Multiplikative Ausdrücke
Der mal-Operator
Der mal-Operator bildet das Produkt seiner Operanden. Seine Funktion ist definiert in op:nemeric-multiply().
Syntax: Operand1 * Operand2
Der div-Operator
Der Divisions-Operator berechnet und definiert den Quotient seiner Operanden. Seine Funktion entspricht op:numeric-divide()
Syntax: Operand1 div Operand2
Der idiv-Operator
Dieser Operator berechnet zwar auch den Quotienten seiner Operanden, jedoch berücksichtigt er den Rest nicht. Die Funktion dieses Operators ist op:numeric-integer divide().
Syntax: Operand1 div Operand2 ( äquivalent zur Syntax xs:integer ( Operand1 div Operand2) )
Der mod-Operator
Der "mod"-Operator berechnet den Rest der einer Division. Seine Funktion ist über op:numeric-mod() definiert. Ist der erste Operand negativ so ist das Ergebnis negativ. Ist das der erste Operand positiv so trifft das auch beim Ergebnis zu.
Syntax: Operand1 mod Operand2
Unäre Ausdrücke
In XQuery sind die unären Operatoren "+" und "-" definiert. Damit die Kompatibilität mit mit XPath 1.0 gewährleistet ist sind in XQuery mehrere aufeinender folgende unäre Operatoren erlaubt. Die unären Operatoren haben außerdem eine höhere Priorität als binäre. Dem zu Folge werden unäre eher ausgewertet.
Unäres-Plus
Der unäre Plus-Operator gibt den Operanden mit unveränderten Vorzeichen zurück. Er ist definiert in der Funktion op:numeric-unary-plus().
Syntax: + Operand
Unäres-Minus
Der unäre Minus-Operator gibt den Operanden mit umgekehrten Vorzeichen zurück. Seine Definition ist op:numeric-unary-minus().
Syntax: - Operand
Aggregatfunktionen
In XQuery werden auch verschiedene Aggregatfunktionen, wie Anzahl, avg, min, max, oder sum, bereitgestellt.
- count() , gibt die Anzahl der Elemente zurück, die in der von $arg angegebenen Sequenz enthalten sind. ( Syntax: fn:count($arg as item()*) )
- avg() , gibt den Mittelwert einer Sequenz von Zahlen zurück.
( Syntax: fn:avg($arg as xdt:anyAtomicType*) ) *min() , gibt aus einer Sequenz atomarer Werte $arg zurück, das eine Element, dessen Wert kleiner als der Wert aller anderen Elemente ist ( Syntax: fn:min($arg as xdt:anyAtomicType*) ) *max() , gibt aus einer Sequenz atomarer Werte $arg zurück, das eine Element, dessen Wert größer als der Wert aller anderen Elemente ist. ( Syntax: fn:max($arg as xdt:anyAtomicType*) ) *sum() , gibt die Summe einer Sequenz von Zahlen zurück. ( Syntax: fn:sum($arg as xdt:anyAtomicType*) )
Vergleichsoperatoren
Allgemeine Vergleiche
Allgemeine Vergleiche sind im Stande Sequenzen mit mehreren Items oder gar einzelne Werte, miteinander zu vergleichen. Jedoch ist der Vergleich von Sequenzen mit mehreren Items implementierungsabhängig. Allgemeine Vergleichsoperatoren sind =, >=, <, <=, > und !=.
Vergleiche von Werten
Diese Arten von Vergleichen können nicht auf Sequenzen mit mehr als einem Item angewendet werden. Sie sind ausschließlich für das Vergleichen von einzelnen Werten zu gebrauchen. Es werden 6 Operatoren für Vergleiche von Werten zur Verfügung gestellt:
- ne (ungleich)
- eq (gleich)
- gt (größer als)
- lt (kleiner als)
- le (kleiner/gleich)
- ge (größer/gleich)
Vergleiche von Knoten
Anhand ihrer Position im XML-Dokument oder ihrer Knoten-ID können die Knoten miteinander verglichen werden. Dabei ist der Rückgabewert entweder true oder falls. Es stehen drei Operatoren für Knotenvergleiche zur Verfügung:
- is-Operator
- <<-Operator
- >>-Operator
Konstruktoren
Mit Hilfe von Konstruktoren können wir XML-Strukturen innerhalb einer Anfrage erstellen. Man unterscheided hierbei direkte Konstruktoren und berechnete Konstruktoren. In geschweiften Klammern eingegrenzte Ausdrücke nennt man "enclosed expressions". Sie werden ausgewertet und durch ihr Ergebnis ersetzt. Konstruktoren kann man benutzen für z.B. Elementknoten, Attributknoten, Dokumentknoten oder auch Kommentarknoten.
Direkte Konstruktoren
Diese Art Konstruktoren verwenden eine XML ähnliche Syntax. Die Ergebnisse dieser Konstruktionen sind Konstanten.Innerhalb direkter Konstruktoren können umschlossene Ausdrücke stehen.
Berechnete Konstruktoren
Berechnete Konstruktoren nutzen umschlossene Ausdrücke als Art der Formulierung. Dabei spezifiziert das Schlüsselwort den Knotentyp "Schlüsselwort Name {Inhalt}". Der Name wird nur dann angegeben, wenn der Knoten auch einen Namen besitzt. Der Inhalt des Konstruktes wird innerhalb der geschweifter Klammer angegeben.
FLWOR - Ausdrücke
FLWOR-Ausdrücke bilden die Grundlage für Anfragen an XML-Dokumente. Der Ausdruck bindet Variablen an Ergebnisse von Ausdrücken, wertet darauf in einer where-Klausel ein Prädikat aus und konstruiert ein neues Dokument als Resultat. FLWOR-Ausdrücke weisen Ähnlichkeiten mit Abfragen im SQL-Syntax auf. FLWOR ist ein Kunstwort (aus dem englischen "Flower"). Die einzelnen Buchstaben entsprechen dabei den Anfangsbuchstaben der Klauseln des Ausdrucks: for, let, where, order und return.
Ein einfacher FLWOR-Ausdruck ist zum Beispiel folgendes:
Dieser Ausdruck gibt alle Filmtitel aus dem Beispiel XML-Dokument "filmliste" zurück.
Mit einer zusätzlichen where-Klausel kann die Ergebnismenge weiter eingegrenzt werden.
Die gleiche Abfrage könnte auch mit Hilfe des folgenden XPath-Ausdrucks ausgeführt werden.
/filmliste/film[jahr=2009]/titel
Der XPath-Ausdruck liefert genau die selbe Ergebnismenge wie der XQuery-Ausdruck. Es gilt: Jeder gültige XPath-Ausdruck ist auch in XQuery zulässig. Jedoch sind FLWOR-Ausdrücke in XQuery weitaus leistungsfähiger, wenn es darum geht, mit Hilfe von Joins Abfragen über mehrere XML-Dokumente auszuführen.
Die for-Klausel
In der for-Klausel wird über eine Sequenz iteriert. Es handelt sich entweder um eine Sequenz von Knoten oder um eine Sequenz aus atomaren Werten. Es kann eine beliebige Operation auf alle Elemente der Sequenz angewendet werden.
Bei $i handelt es sich um die Iterationsvariable, welche jeden Wert der Sequenz einmal annimmt. Es ist mehr als eine for-Klausel pro Ausdruck möglich.
Ein FLWOR-Ausdruck kann an jeder beliebigen Stelle stehen an der ein Ausdruck erlaubt ist. Beispielsweise kann ein FLWOR-Ausdruck als Argument an eine Funktion übergeben werden.
Die Funktion avg() berechnet den Durchschnitt aus der Sequenz, welche der FLWOR-Ausdruck zurückgibt. Im Beispiel wird die durchschnittliche Anzahl der Regisseure ermittelt, die an einem Film gearbeitet haben.
where $filme/titel = "Sin City" return <besetzung>{ ( for $schauspieler in //schauspielerliste/schauspieler where $schauspieler/filmid = $filme/@id return <schauspieler>{($schauspieler/vorname, $schauspieler/name)}</schauspieler> ) }</besetzung>
Die Ergebnismenge der obigen Anfrage:
<besetzung> <schauspieler> <vorname>Jessica</vorname> <name>Alba</name> </schauspieler> <schauspieler> <vorname>Rosario </vorname> <name>Dawson</name> </schauspieler> <schauspieler> <vorname>Elijah </vorname> <nam>Wood</name> </schauspieler> <schauspieler> <vorname>Bruce </vorname> <name>Willis</name> </schauspieler> </besetzung>
Vordefinierte Funktionen
In XQuery gibt es mehr als 100 vordefinierte Funktionen, die die Datenabfrage aus XML-Dokumenten unterstützen. Beispielsweise die data Funktion. Mit ihrer Hilfe kann der Wert eines Knotens zurückgegeben jedoch nicht der komplette Knoten mit Start- und Endtag.
Unter anderem gibt es Funktionen für die Arbeit mit Strings, Datumsangaben, Knoten, Sequenzen und boolschen Werten.
Eine Übersicht über vordefinierte XQuery Funktionen findet sich hier.
http://www.xqueryfunctions.com/
Benutzerdefinierte Funktionen
XQuery bietet die Möglichkeit Funktionen selbst zu deklarieren. Eine benutzerdefinierte Funktionen beginnt mit declare function gefolgt von einem Präfix extern oder local. Lokale Funktionen innerhalb eines Hauptmoduls werden mit dem Präfix local definiert. Local ist an den Namensraum http://www.w3.org/2005/xquery-local-functions gebunden. Des Weiteren besteht die Funktion aus einem Funktionskopf, welcher den Namen der Funktion enthält. Sowie die an die Funktion übergebenen Argumente und dem Datentyp des Rückgabewertes. Den Funktionsrumpf bildet ein Xquery-Ausdruck.
Benutzerdefinierte Funktionen können auch rekursiv definiert werden.
If-Then-Else Anweisungen
XQuery unterstütz If-Then-Else Anweisungen. Dabei wird wie auch in anderen Sprachen üblich in Abhängigkeit eines boolschen Wertes, entweder der then-Ausdruck oder der else-Ausdruck einer If-Then-Else Anweisung ausgewertet. Der zu testende Ausdruck muss in Klammern stehen. Das else muss in XQuery immer enthalten sein. Wenn es nicht benötigt wird kann auch () (leere Sequenz) zurückgegeben werden. Es ist möglich mehrere If-Then-Else –Anweisungen zu schachteln.
Datums- und Zeitausdrücke
Das Rechnen mit Zeitausdrücken in XQuery ist sehr komfortabel. Beispielsweise ist es sehr schnell möglich den Zeitraum zwischen zwei Datumsangaben zu berechnen, wie das Beispiel zeigt.
Auf die selbe Art und Weise können einzelne Zeiträume zu einem großen Zeitraum addiert werden. Weiterhin bietet XQuery vordefinierte Funktionen an um aus Zeiträumen die Anzahl der Tage, Stunden etc. zu extrahieren.
Quellen / Weiterführendes
Quellen
- Helmut Vonhoegen: Einstieg in XML, Galileo Computing, 2011
- Alfred Moss: XQuery und SQL/XML in DB2-Datenbanken, Vieweg + Teubner, 2008
Weiterführende Links
http://www.w3.org/TR/xquery-update-10/