XQuery
Transcrição
XQuery
h_da WS 2014/2015 XQuery Seite 1 XQUERY XQuery ist eine Suchanfragen Sprache mit der Funktionalität: • Selektieren von Elementen und Attributen in einem Dokument • J oin von mehreren Dokumenten • Ändern von Daten • Berechnen neuer Daten h_da WS 2014/2015 • Hinzufügen von Elementen und Attributen zum Ergebnis • Sortieren der Ergebnisse Seite 2 XQuery Sprachelemente • Aufbau eines XQL Dokuments • Namespace Deklarationen • Variablen Deklarationen • FLWOR Ausdrücke h_da WS 2014/2015 • Input Funktionen Seite 3 Aufbau eines XQL Dokuments Module ::= VersionDecl? MainModule MainModule ::= Prolog QueryBody Prolog ::= ((DefaultNamespaceDecl | NamespaceDecl | Import) Separator)* h_da WS 2014/2015 ((VarDecl | FunctionDecl) Separator)* Separator ::= ";" QueryBody ::= Expr Expr ::= ExprSingle ("," ExprSingle)* Seite 4 Xquery: Version Declaration Beispiele für Version Declaration: xquery version "1.0"; h_da WS 2014/2015 xquery version "1.0" encoding "utf-8"; Seite 5 XQuery – Namespace Deklaration Vordefinierte Namespaces in XQuery: • xml = http://www.w3.org/XML/1998/namespace • xs = http://www.w3.org/2001/XMLSchema • xsi = http://www.w3.org/2001/XMLSchema-instance • fn = http://www.w3.org/2005/xpath-functions • xdt = http://www.w3.org/2005/xpath-datatypes h_da WS 2014/2015 • local = http://www.w3.org/2005/xquery-local-functions Seite 6 XQuery – Variablen Deklaration Typ und Initialisierungswert der Variablen werden definiert: declare variable $x as xs:integer := 7; Kein Typ, aber Initialisierungswert der Variablen wird definiert: declare variable $x := 7.5; Typ, aber kein Initialisierungswert der Variablen werden definiert. EXTERNAL bedeutet, der Wert der Variablen wird von extern bereitgestellt: declare variable $x as xs:integer external; h_da WS 2014/2015 Beispiel einer Variablendeklaration mit qualifizierten Namen: declare variable $math:pi as xs:double := 3.14159E0; Seite 7 XQuery Literale Literal ::= NumericLiteral | StringLiteral NumericLiteral ::= IntegerLiteral | DecimalLiteral | DoubleLiteral IntegerLiteral ::= Digits DecimalLiteral ::= ("." Digits) | (Digits "." [0-9]*) DoubleLiteral ::= (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits StringLiteral ::= ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'") h_da WS 2014/2015 PredefinedEntityRef Digits ::= ::= [0-9]+ "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";" Seite 8 XQuery Literale Diese Definition der vorhergehenden Folie bedeutet, dass Literale anderer Datentypen durch die cast-Operation definiert werden müssen: Beispiele: declare variable $dz as xs:date := xs:date("2002-12-22"); h_da WS 2014/2015 declare variable $i as xs:int := xs:int(2345); Seite 9 XQuery Function Declaration declare function local:order-value($po as element(purchase-order)) as xs:double { sum($po/order-item/(@price * @quantity)) }; --------------- Aufruf -------------------------------------------local:order-value(doc('purchaseOrder.xml')/purchase-order) --------------- XML-File -----------------------------------------<purchase-order> <red-tape/> h_da WS 2014/2015 <order-item product="p010" price="10.50" quantity="2"/> <order-item product="p020" price="18.10" quantity="8"/> </purchase-order> Seite 10 XQUERY Für XQuery gibt es eine non-XML Syntax und eine XML Syntax. Wir betrachten die non-XML Syntax: • XQuery ist case-sensitive • XQuery Elemente, Attribute, und Variablen müssen valide XML Namen sein. • Ein XQuery String kann mit einfachem oder DoppelQuote geschrieben werden. • Eine XQuery Variable wird definiert mit $ gefolgt von einem Namen, e.g. $bookstore h_da WS 2014/2015 • XQuery Kommentare werden mit (: und :) geklammert, z.B. (: XQuery Kommentar :) Die XML Syntax ist beschrieben in: http://www.w3.org/TR/xqueryx/ Seite 11 Aufbau eines XQL Dokuments: Ausdrücke Module ::= VersionDecl? MainModule MainModule ::= Prolog QueryBody Prolog ::= ((DefaultNamespaceDecl | NamespaceDecl | Import) Separator)* h_da WS 2014/2015 ((VarDecl | FunctionDecl) Separator)* Separator ::= ";" QueryBody ::= Expr Expr ::= ExprSingle ("," ExprSingle)* Seite 12 XQuery: Primär-Ausdrücke PrimaryExpr ::= Literal | VarRef | ParenthesizedExpr | ContextItemExpr | FunctionCall | OrderedExpr | h_da WS 2014/2015 UnorderedExpr | Constructor Seite 13 Konstruktion von Knoten XML Strukturen können dynamisch aufgebaut werden (return Klausel im Beispiel) Definition: Ein direct constructor ist ein Konstruktor, bei dem der Name des konstruierten Elements eine Konstante ist. Ein Konstruktor für ein Element entspricht genau der XML-Syntax für ein Element. Wichtig: Ist der Text im Inhalt in geschweiften Klammern { }, wird er als Ausdruck behandelt, das Ergebnis des Ausdrucks ist der Inhalt (enclosed expression) h_da WS 2014/2015 Beispiel: <Buch Preis={2*$i}>{$b/Titel}</Buch> Seite 14 Konstruktion von Knoten Definition: Ein computed constructor ist ein Konstruktor, der mit dem Namen des konstruierten Knotens beginnt. Es gibt die Knoten: » Dokument document » Element element » Attribut attribute » Text text » Kommentar comment h_da WS 2014/2015 » Processing Instruction processing-instruction Seite 15 Konstruktion von Knoten Element-Konstuktion: CompElemConstructor ::= "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}" ContentExpr ::= Expr Beispiel1: element book { attribute isbn {"isbn-0060229357" }, element title { "Harold and the Purple Crayon"}, element author { element first { "Crockett" }, h_da WS 2014/2015 element last {"Johnson" } } } Seite 16 Konstruktion von Knoten Element-Konstuktion: Beispiel2: <entry word="address"> <variant xml:lang="de">Adresse</variant> <variant xml:lang="it">indirizzo</variant> </entry> element {$dict/entry[@word=name($e)]/variant[@xml:lang="it"]} {$e/@*, $e/node()} h_da WS 2014/2015 Es gelte: $dict ist ein Dictionary gebunden, das aus entrys besteht $e ist gebunden an: <address>123 Roosevelt Ave. Flushing, NY 11368</address> Ergebnis ist dann: <indirizzo>123 Roosevelt Ave. Flushing, NY 11368</indirizzo> Seite 17 XQuery - Ausdrücke Module ::= VersionDecl? MainModule ::= Prolog QueryBody QueryBody ::= Expr MainModule Expr ::= ExprSingle ("," ExprSingle)* ExprSingle ::= FLWORExpr | QuantifiedExpr h_da WS 2014/2015 | TypeswitchExpr | IfExpr | OrExpr Seite 18 FLWOR-Ausdrücke - Details FLWORExpr ::= (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle ForClause ::= "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)* LetClause ::= "let" "$" VarName TypeDeclaration? ":=" ExprSingle h_da WS 2014/2015 ("," "$" VarName TypeDeclaration? ":=" ExprSingle)* Seite 19 FOR - Klausel ForClause ::= "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)* Bindet eine oder mehrere Variablen an das Ergebnis des Ausdrucks. Es entsteht eine Schleife über der Potenzmenge der Ausdrucksergebnisse für die einzelnen Variablen (Tupel) for $i in (1, 2), $j in (3, 4) ($i = 1, $j = 3) h_da WS 2014/2015 ($i = 1, $j = 4) ($i = 2, $j = 3) ($i = 2, $j = 4) Seite 20 FOR – Klausel: PositionalVar PositionalVar ::= "at" "$" VarName Eine in der for- Klausel gebundene Variabel kann eine zugeordnete PositionalVariable haben (Variable nach dem „at“). Diese Variable ist immer vom Type xs:integer und iteriert über die Position der For- h_da WS 2014/2015 Variablen in der Sequenz. Sie startet bei 1. Seite 21 FOR – Klausel: PositionalVar for $car at $i in ("Ford", "Chevy"), $pet at $j in ("Cat", "Dog") ($i = 1, $car = "Ford", $j = 1, $pet = "Cat") ($i = 1, $car = "Ford", $j = 2, $pet = "Dog") h_da WS 2014/2015 ($i = 2, $car = "Chevy", $j = 1, $pet = "Cat") ($i = 2, $car = "Chevy", $j = 2, $pet = "Dog") Seite 22 LET - Klausel LetClause ::= "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)* Die LET – Klausel kann eine oder mehrere Variablen haben. Es findet keine Iteration wie in der FOR-Klausel statt. h_da WS 2014/2015 Die Variablen Bindungen werden denen der FOR-Klausel hinzugefügt. . Seite 23 Where - Klausel WhereClause ::= "where" ExprSingle Filtert die durch for und let selektierten Tupel, d.h. Nur Tupel mit dem Wert true werden weiterbearbeitet. Ein ExprSingle in der Where-Klausel ist zumeist ein Vergleichsausdruck, kann aber auch: • Ein bedingter Ausdruck sein (if) • Ein boolescher Ausdruck (OR, AND, NOT) h_da WS 2014/2015 • Ein quantifizierter Ausdruck sein (some, every) • Ein FLWOR Ausdruck sein Seite 24 XQuery – Ausdrücke – Quantified Ausdruck Existenz-Quantor: („es gibt“): some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4 Universal-Quantor: („für alle“): every $x in (1, 2, 3), $y in (2, 3, 4) h_da WS 2014/2015 satisfies $x + $y = 4 Seite 25 XQuery – Ausdrücke – Quantified Ausdruck: some xquery version "1.0"; <results> <result>Es gibt { let $books := doc("books.xml")/bookstore, $res := some $price in $books/book/price satisfies $price > 45 return if($res) then "mindestens ein" else "kein" h_da WS 2014/2015 } Buch, das teurer als 45$ ist. </result> </results> Seite 26 XQuery – Ausdrücke – Quantified Ausdruck: every xquery version "1.0"; <results> <result>{ let $books := doc("books.xml")/bookstore, $res := every $year in $books/book/year satisfies $year < 2005 return if($res) then "Alle" else "Nicht alle" h_da WS 2014/2015 } Bücher sind vor 2005 veröffentlicht worden. </result> </results> Seite 27 XQuery – Ausdrücke - Typeswitch TypeswitchExpr ::= "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle CaseClause ::= h_da WS 2014/2015 "case" ("$" VarName "as")? SequenceType "return" ExprSingle Seite 28 XQuery – Ausdrücke - Typeswitch typeswitch($customer/billing-address) Case $a as element (*, USAddress) return $a/state case $a as element (*,CanadaAddress) return $a/province case $a as element (*, JapanAddress) return $a/prefecture h_da WS 2014/2015 default return ''unknown'' Annahme: $a ist an eine billing-address Element gebunden. Seite 29 XQuery – Ausdrücke - Typeswitch declare function local:dispatch($node as node()) as item()* { typeswitch($node) case text() return $node case comment() return $node case element(bill, billType) return local:bill($node) case element(btitle) return local:btitle($node) case element(section-id) return local:section-id($node) case element(bill-text) return local:bill-text($node) h_da WS 2014/2015 case element(strike) return local:strike($node) default return local:passthru($node) }; Seite 30 XQuery – Ausdrücke – If- Ausdruck if ($part/@discounted) then $part/wholesale else $part/retail Grammatik: h_da WS 2014/2015 IfExpr ::= "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle Seite 31 XQuery – Ausdrücke – Or- Ausdruck OrExpr ::= AndExpr ( "or" AndExpr )* AndExpr ::= ComparisonExpr ( "and" ComparisonExpr )* ComparisonExpr ::= RangeExpr ( (ValueComp | GeneralComp | NodeComp) h_da WS 2014/2015 RangeExpr )? ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge" GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">=" NodeComp ::= "is" | "<<" | ">>" Seite 32 XQuery Knotenvergleich : Beispiel if ( //ProgramInformation[1]//Keyword [1] is //ProgramInformation[1]//Keyword[contains (., „Gesundheit“)] ) then <Result>ja</Result> else h_da WS 2014/2015 <Result>nein</Result> Seite 33 FLWOR-Ausdrücke - Beispiel for $d in doc("depts.xml")/depts/deptno let $e := doc("emps.xml")/emps/emp[deptno = $d] where count($e) >= 10 order by avg($e/salary) descending return <big-dept> { $d, <headcount>{count($e)}</headcount>, <avgsal>{avg($e/salary)}</avgsal> h_da WS 2014/2015 } </big-dept> Seite 34 XQuery – Input Funktionen Funktion: doc($uri as xs:string?) as document-node()? Beschreibung: Liefert einen Dokumentknoten entsprechend der URI Ist der Parameter leer, liefert er das leere Ergebnis Beispiel: h_da WS 2014/2015 doc(„ServiceDescription_v1.13.xml“) Seite 35 XQuery – Input Funktionen Funktion: collection() as node()* collection($arg as xs:string?) as node()* Beschreibung: Liefert eine Folge von Dokumentknoten entsprechend der URI Ist der Parameter leer, liefert sie die Default Collection (Implementations-definiert) Beispiel: h_da WS 2014/2015 collection('http://www.iese.fraunhofer.de/h_da') Seite 36 XQUERY XQuery gibt es in zwei Versionen: XQuery 1.0: XQuery 1.0: An XML Query Language (Second Edition) Recommendation vom 14.12.2010. XQuery 3.0: XQuery 3.0: An XML Query Language vom 08.04.2014. Einige Erweiterungen: • Try/Catch Expressions: Fehlerbehandlung bei dynamischen Fehlern h_da WS 2014/2015 • Switch Expression: Alternativen je nach Wert. • group by clause in FLWOR Expressions: Durchführung der Return Clause gruppiert Seite 37