650 likes | 810 Views
XQuery. Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt. XPath (Wiederholung). Anfragesprache auf XML XPath-Expressions selektieren Knoten des Eingabe-Dokuments. bib. book. /bib//title. book. title. author. title. author. XPath (Wiederholung).
E N D
XQuery Informationssysteme, 14.06.2007 Vortragender: Michael Schmidt
XPath (Wiederholung) • Anfragesprache auf XML • XPath-Expressions selektieren Knoten des Eingabe-Dokuments bib book /bib//title book title author title author
XPath (Wiederholung) • Path Steps: axis::nodetest • Axen: „child“, „descendant“, „ancestor“, „following“, „following-sibling“, ... • Node-tests: Tag, „*“, „node()“, „text()“ • Absolute Pfade: /step/step/… • Relative Pfade: step/step/...
XQuery • „SQL für XML“ • W3C Recommendation • Funktionale Programmiersprache, Turing-vollständig • XQueries enthalten XPath Ausdrücke • Ergebnis einer XQuery: wohlgeformte XML-Dokumente (XPath: Menge von Knoten) • Keine Datenmanipulationssprache (z.B. keine Updates)
Node-Construction und Konstanten XQuery Ergebnis <result> <text>"Hello World"</text> </result> <result> <text>"Hello World"</text> </result> XQuery Ergebnis <result> <text>{"Hello World"}</text> </result> <result> <text>Hello World</text> </result>
Dokument-Zugriff bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <books> { doc("bookstore.xml")/bib/book[price>30] } </books> Ergebnis <books> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> </books>
Sequenz bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <titles> { ( doc("bookstore.xml")/bib/article/title, doc("bookstore.xml")/bib/book/title ) } </titles> Ordnung bleibt erhalten! Ergebnis <titles> <title>T3</title> <title>T1</title> <title>T2</title> </titles>
FR-Expression bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <booktitles> { for $book in doc("bookstore.xml")//book return $book/title } </booktitles> Ergebnis <booktitles> <title>T1</title> <title>T2</title> </booktitles>
FWR-Expressions bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <booktitles> { for $book in doc("bookstore.xml")//book where $book/price>30 return <booktitle>{ $book/title/text() }</booktitle> } </booktitles> Konstruktion von Knoten, die im Dokument nicht vorkommen Ergebnis <booktitles> <booktitle>T1</booktitle> </booktitles>
FLWR-Expressions bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <booktitles> { for $book in doc("bookstore.xml")//book let $booktitle := <bt>{ $book/title/text() }</bt> where ($book/price>30) return $booktitle } </booktitles> Ergebnis <booktitles> <bt>T1</bt> </booktitles>
FLWOR-Expressions bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <booktitles> { for $book in doc("bookstore.xml")//book let $booktitle := $book/title where ($book/price>10) order by $booktitle/text() descending return <bt>{ $booktitle/text() }</bt> } </booktitles> Ergebnis <booktitles> <bt>T2</bt> <bt>T1</bt> </booktitles>
Where-Expressions bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> • Konnektive and, or, fn:not XQuery <booktitles> { for $book in doc("bookstore.xml")//book where ($book/price>10 and fn:not($book/author/text()="A1")) return $book/title } </booktitles> Ergebnis <booktitles> <title>T2</title> </booktitles>
Some-Expressions XQuery <booktitles> { for $book in doc("bookstore.xml")//book where (some $a in $book/author satisfies $a/text()="A2") return $book/title } </booktitles> bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <author>A2</author> </book> <book> <title>T2</title> <author>A3</author> <author>A4</author> </book> </bib> Ergebnis <booktitles> <title>T1</title> </booktitles>
For vs let-Expressions Ergebnis <for> <test>1</test> <test>2</test> <test>3</test> <test>4</test> <test>5</test> </for> XQuery 1 <for>{ for $x in (1 to 5) return <test> {$x} </test> }</for> Iteration XQuery 2 Ergebnis <let>{ let $x:=(1 to 5) return <test> {$x} </test> }</let> <let> <test>1 2 3 4 5</test> </let> keine Iteration
If-then-else Expressions XQuery bookstore.xml <booktitles> { for $book in doc("bookstore.xml")//book return if (fn:exists($book/price)) then <priced>{ $book/title }</priced> else <unpriced>{ $book/title }</unpriced> } </booktitles> <bib> <book> <title>T1</title> <author>A1</author> </book> <book> <title>T2</title> <author>A2</author> <price>30</price> </book> </bib> Ergebnis <booktitles> <unpriced><title>T1</title></unpriced> <priced><title>T2</title></priced> </booktitles>
Vordefinierte Funktionen • Zahlreiche built-in Functions: • Boolean: fn:exists(), fn:empty() … • String Manipulation: fn:concat(), fn:uppercase() … • String Tests: fn:contains(), fn:starts-with() … • Sequenzen: fn:exactly-one(), fn:distinct-values() … • Mathematisch: fn:floor(), fn:round(), fn:abs() … …
Vordefinierte Funktionen bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <booktitles> { for $book in doc("bookstore.xml")//book where (fn:exists($book/price) and fn:contains($book/author, "A")) return $book/title } </booktitles> Ergebnis <booktitles> <title>T1</title> <title>T2</title> </booktitles>
XQuery Joins • Vergleich unterschiedlicher Teile des Eingabe-Dokuments • Auch Joins zwischen verschiedenen Dokumenten möglich • Im Gegensatz zu SQL-Joins, oftmals nicht leicht zu erkennen, da keine eigene Syntax (kein JOIN-Keyword) • Optimierung der Auswertung von Joins durch herkömmliche und XML-spezifische Methoden
XQuery Joins XQuery Ergebnis <titles> { for $bib in doc("bookstore.xml")/bib return for $book in $bib/book return for $article in $bib/article where $book/author=$article/author return <pair>{ $book/title, $article/title}</pair> } </titles> <titles> <pair> <title>T1</title> <title>T4</title> </pair> </titles> $article $book bib article article book book title author title author title author title author T3 A3 T4 A1 T1 A1 T2 A2
XQuery Joins • Join über zwei Dokumente XQuery <books-with-prices> { for $a in doc("www.amazon.com/review.xml")//book for $b in doc("www.bn.com/bib.xml")//entry where $a/isbn = $b/isbn return <book-with-prices> { $b/title } <amazon> { $a/price/text() } </amazon> <bn> { $b/price/text() } </bn> </book-with-prices> } </books-with-prices>
Aggregatfunktionen • fn:min(), fn:max(), fn:count(), fn:sum(), fn:avg() XQuery bookstore.xml <booktitles> { for $book in doc("bookstore.xml")//book return { ($book/title, <authors>{ fn:count($book/author) }</authors>) } } </booktitles> <bib> <book> <title>T1</title> <author>A1</author> <author>A2</author> </book> <book> <title>T2</title> <author>A3</author> </book> </bib> Ergebnis <booktitles> <title>T1</title><authors>2</authors> <title>T2</title><authors>1</authors> </booktitles>
Aggregatfunktionen adressen.xml <adressliste> <adresse> <ort> <name>SB</name> <plz>66121</plz> </ort> <strasse>S1</strasse> </adresse> <adresse> <ort> <name>SB</name> <plz>66121</plz> </ort> <strasse>S2</strasse> </adresse> … </adressliste> Beispiel: Gegeben Adressdatenbank, berechne Orte und Zahl der Adressen für Orte mit mind. 2 Adressen Ergebnis SB66121, NK66538, … <adressliste> { for $o in fn:distinct-values(doc("adressen.xml")//ort) let $ort:=doc("adressen.xml")//ort[self::node()=$o] where fn:count($ort)>=2 order by $o return <ortsliste> <ort>{($ort[1]/name,$ort[1]/plz)}</ort> <anzahl>{count($ort)}</anzahl> </ortsliste> } </adressliste>
Datentransformation • XML: Generalisierung von HTML • XQuery ermöglicht Anfragen auf XML-Dokumente und direkte Ausgabe von HTML • XML und XQuery in Web-Szenarien gut geeignet
Datentransformation bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> <price>50</price> </book> <book> <title>T2</title> <author>A2</author> <price>20</price> </book> <article> <title>T3</title> <author>A3</author> </article> </bib> XQuery <html> <head> <title>Angebot</title> </head> <body> <h1>Buchliste</h1> <table border="1">{ for $book in doc("bookstore.xml")//book return <tr> <td><b>{$book/title/text()}</b></td> <td>{$book/author/text()}</td> </tr> }</table> </body> </html>
Datentransformation Ergebnis <html> <head> <title>Angebot</title> </head> <body> <h1>Buchliste</h1> <table border=1> <tr> <td><b>T1</b></td> <td>A1</td> </tr> <tr> <td><b>T2</b></td> <td>A2</td> </tr> </table> </body> </html>
Vielfalt an Konstrukten • FLWOR – Expressions • Aggregationen • Typkonversionen (nicht besprochen) • Gleichheit von Knoten • (Benutzerdefinierte) Funktionen Sehr komplex, effiziente Auswertung von XQuery noch immer ein aktives Forschungsgebiet
XQ – ein XQuery Fragment Syntax Composition-free XQ query ::= Ɛ | <a>query</a> | query query | var | var/axis::v | for var in var/axis::v return query | if cond then query else query cond ::= var = var | var = <a/> | true | some var in var/axis::v satisfies cond | cond and cond | cond or cond | not cond
Composition-free XQuery XQuery <books> { let $x := <booklist>{ for $book in /bib/book return <b>{ $book } </b> }</booklist> for $b in $x/booklist/b return $b/* } </books> bib book book
Composition-free XQuery XQuery <books> { let $x := <booklist>{ for $book in /bib/book return <b>{ $book } </b> }</booklist> for $b in $x/booklist/b return $b/* } </books> $x booklist $book bib b b book book book book neu konstruiert
Composition-free XQuery XQuery <books> { let $x := <booklist>{ for $book in /bib/book return <b>{ $book } </b> }</booklist> for $b in $x/booklist/b return $b/* } </books> $x booklist $b $book bib books b b book book book book book book
Composition-free XQuery XQuery <books> { let $x := <booklist>{ for $book in /bib/book return <b>{ $book } </b> }</booklist> for $b in $x/booklist/b return $b/* } </books> in der Praxis:viele XQuery Anfragen mit Kompositionkönnen in äquivalente XQ-Anfragenumgeschrieben werden <books>{ for $book in /bib/book return $book }</books> XQ query
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x y y Ergebnis <r>
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x $y y y Ergebnis <r><y/>
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x $y y y Ergebnis <r><y/><y/>
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x y y Ergebnis <r><y/><y/>
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x $y y y Ergebnis <r><y/><y/><y/>
niedrigere Komplexität in der Auswertung Variablen binden immer an einen Knoten im Eingabebaum Eigenschaft von XQ XQ expression <r>{ for $x in //x return for $y in $x//y return $y}</r> r $x x x $y y y Ergebnis <r><y/><y/><y/><y/><r/>
XQ formale Semantik • Ergebnis: Liste von Knoten k: Anzahl gebundener Variablen e: derzeitiges environment (Variablenbindung) “false” als leere Liste
XQ Evaluierung [[<r>{ $x2$x1}</r>]]2 (<a/>,<b/>) = [<r> [[$x2$x1]]2 (<a/>,<b/>) </r>] = [<r> [[$x2]]2 (<a/>,<b/>) [[$x1]]2 (<a/>,<b/>) </r>] = [<r> <b/> <a/> </r>]
XQ Evaluierung bookstore.xml <bib> <book> <title>T1</title> <author>A1</author> </book> <book> <title>T2</title> <author>A2</author> </book> </bib> XQuery <bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else () }</bt>
XQ Evaluierung [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung [[if (some …)]]1 (l1) + [[if (some …)]]1 (l2) l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung [[if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some …)]]1 (l1) + [[if (some …)]]1 (l2) l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung [[for $author in $book/author return $author/text()=“A1”]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some …)]]1 (l1) + [[if (some …)]]1 (l2) l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung l =[[$book/author]]1 (<book><author>A1</author> <title>T1</title></book>) =[<author>A1</author>] [[$author/text()=“A1”]]2 (<book>…</book>, <author>A1</author>) [[for $author in $book/author return $author/text()=“A1”]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some …)]]1 (l2) + [[if (some …)]]1 (l1) l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()
XQ Evaluierung l =[[$book/author]]1 (<book><author>A1</author> <title>T1</title></book>) =[<author>A1</author>] [[$author/text()=“A1”]]2 (<book>…</book>, <author>A1</author>) [<yes/>] [[$author/text()]]2 (…) [“A1”] [[“A1”]]2 (…) [“A1”] [[for $author in $book/author return $author/text()=“A1”]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]1 (<book><author>A1</author><title>T1</title></book>) [[if (some …)]]1 (l1) + [[if (some …)]]1 (l2) l=[[//book]]0 () = [<book><author>A1</author><title>T1</title></book>, <book><author>A2</author><title>T2</title></book>] [[for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()]]0 () [[<bt>{ for $book in //book return if (some $author in $book/author satisfies $author/text()=“A1”) then $book else ()}</bt>]]0 ()