450 likes | 652 Views
XQuery. Dotazovací jazyk nad XML dokumenty Jan V ávra , Přemysl Volf jan.vavra @matfyz.cz 7. ledna 2004 http://xien.jikos.cz/document/xquery.ppt. Úvod. datový model XML dokumentu tříděný strom výrazy v XQuery cesta, iterace, podmínka, funkce typy XSchema, validace dodatek
E N D
XQuery Dotazovací jazyk nad XML dokumenty Jan Vávra, Přemysl Volf jan.vavra@matfyz.cz 7. ledna 2004 http://xien.jikos.cz/document/xquery.ppt
Úvod • datový model XML dokumentu • tříděný strom • výrazy v XQuery • cesta, iterace, podmínka, funkce • typy • XSchema, validace • dodatek • XML a relační db, DIS, schémata
Datový model XML dokument: • sekvence - tříděný seznam uzlů nebo atomických proměnných • atomická hodnota: číslo, řetězec, datum • uzel: • dokument • element • atribut • text • komentář • instrukce • deklarace namespace (jmenného prostoru)
Datový model - uzel Má: • identita • rozlišení dvou uzlů stejného jména a hodnot • pořadí v dokumentu v dané úrovni zanoření uzlu • konzistence pořadí Může mít: • jiné uzly jako potomky (rekurzivní definice stromu) • jméno (název elementu, atributu, …) • hodnotu nějakého typu(XSchema) • sekvence 0 nebo více atomických hodnot
Datový model - dodatek • Sekvence • seznam heterogenních prvků • sekvence délky 1 ~ jednomu prvku • sekvenence délky 0 povoleny ~ NULL v SQL • Validace XML proti schématu • uzlu nebo atomu přiřadí typ • není ve schématu: • uzel <- anyType • atomická hodnota <- anySimpleType
Datový model - příklad <zboží> <položka status=“v dražbě”> <číslo-položky>4456</číslo-položky> <prodejce>Smith</prodejce> <popis>obraz</popis> <cena>5000</cena> </položka> <položka> ……… </položka> ……… ……… </zboží>
Výrazy v XQuery • XQuery - funkcionální jazyk • sestaven z výrazů • výrazy bez vedlejších efektů • Výrazy: • literál • proměnná • volání funkce • cesta (path expression) • predikát • podmínka • FLWR • funkce
Literál • jednoduchý • číslo: 47 integer, 4.7 decimal, 4.7E3 double • řetězec: ‘xquery’, “xquery” string • složitější • vytvoření pomocí konstruktoru datum: date(“2004-1-31” ) • sekvence • tvoří se pomocí operátoru čárka nebo to • 1,2,3 = (1,2,3) = ( (1,2), (), 3) = 1 to 3
Proměnná • začíná $: $tohle_je_promenna • přiřazení: LET $a := 15 • hodnotou proměnné může být i uzel • žádné vedlejší efekty • hodnotu proměnné nelze měnit
Aritmetika • +, -, *, div, mod • sum(), avg(), count(), max(), min() • funkce pracuje na sekvenci • div : odlišit od / (cesta v xml) • - : musí začínat mezerou - odlišit od názvu elementu
Výraz cesty • založeno na syntaxi XPath 2.0 • série kroků oddělených ‘/’ • vyhodnocení v rámci kontextového uzlu • směr (osa) cesty - XQuery podporuje: • / child (přímý potomek) • // descendant (potomek ~ existuje cesta rodič-potomek délky >=1) • .. parent (rodič) • . self (ukazatel sám na sebe) • @ atribut (ukazatel na atribut) • descendant-or-self (podstrom určený uzlem self) • vyhodnocení probíhá po krocích • element vs. atribut - jméno atributu odlišeno @ před jménem
Výraz cesty – příklad 1 • Vypiš popis všech položek k prodeji od pana Smithe document(‘zboží.xml’)/*/položka[prodejce = ‘Smith’]/popis • Průběh vyhodnocení: • document() - vrátí uzel typu dokument • /*- vrátí všechny potomky a uzlu dokument • /položka - vrátí potomkyb uzlůas názvem položka • /položka[prodejce = ‘Smith’] - omezí potomky b na ty, které mají potomka prodejce s hodnotou Smith • /popis - vrátí potomky c uzlů b s názvem popis
Výraz cesty – příklad 2 • Vypiš všechny elementy popis v dokumentu document(‘zboží.xml’)//popis • Najdi atribut status položky, která je rodič daného popisu $popis/../@status
Predikáty • výraz XQuery ohraničený [ ], který se používá pro filtrování sekvence uzlů • položka[prodejce = ‘Smith’] • Vybere pouze ty položky, které obsahují element prodejce s hodnotou Smith • položka[ cena > 1000 ] • testuje se položka/cena > 1000 • položka [5] • 5. položka v sekvenci • položka [cena] • test na existenci podelementu cena elementu položka
Porovnávací operátoryhodnoty, obecné • porovnání hodnoty • eq, ne, lt, le, gt, ge • skalární hodnoty nebo sekvence délky 1, jinak výjimka • obecné porovnání • =, !=, <, <=, >, >= • rozdíl? - v kardinalitě • položka [cena gt 1000] • existuje právě jeden element cena • má hodnotu větší než 1000 • položka [cena > 1000] • existuje alespoň jedenelement cena • má hodnotu větší než 1000
Porovnávací operátory uzel, pořadí, logické • uzel • is, isnot • porovnání identity • pořadí • <<, >> • $uzel1 << $uzel2 - $uzel1 před $uzel2 • logické • and, or • položka [ prodejce = ‘Smith’ and cena ] • negace • not() • spíše funkce než operátor
Konstruktor elementů • výraz cesty • umí pouze vybrat určité uzly • neumí vytvořit nový element • jednoduchý konstruktor elementu - element • konstruktor s vyhodnocením • výraz XQuery ohraničený { } • hodnotou výrazu může být sekvence atomických hodnot, elementů, atributů • příklad: <položka status=“{ $s }”> <počet-nabídek> { max ( $nabídky [ číslo-položky = $i]/počet-nabídek ) } </počet-nabídek> </položka>
element { $název } { $atributy, $obsah } attribute { $název } { $hodnota-atributu} element { name($e) } { $e/@*, data($e)*2 } attribute { if $p/pohlaví=‘M’ then ‘muž’ else ‘žena’ } { $p/jméno} z elementu vytvoří atribut Dynamický konstruktor computed element | atribute constructor předchozí konstruktor - jen obsah, neumí název nového elementu
Podmínka a kvantifikace • if … then … else … • Musí být obě větve, část if v závorkách • kvantifikované výrazy: some $a in (5,7,9,11) satisfies $a > 10 - true every $a in (5,7,9,11) satisfies $a > 10 - false
Iterace • for $a in (2,3) return $n +1 • hodnotou tohoto výrazu je (3,4) • vnořené cykly: for $m in (2,3), $n in (5,10) return <fakt> {$m} * {$n} = {$m * $n} </fakt> <fakt>2*5 = 10 </fakt> <fakt>2*10 = 20 </fakt> <fakt>3*5 = 15 </fakt> <fakt>3*10 = 30 </fakt>
FLWR (flower) • for - iterace prvků podle sekvence • let - přiřazení hodnot pomocných proměnných , volitelná • where - filtrace výsledné sekvence, volitelná • return - konstrukce výsledku for $i in (1, 5) let $sq= $i * $I where $i < 4 return $sq 1 4 9
<zboží> <položka status=“v dražbě”> <číslo-položky>4456</číslo-položky> <prodejce>Smith</prodejce> <popis>obraz</popis> <cena>5000</cena> <datum>4-1-2004</datum> </položka> <položka> ……… </položka> ……… ……… </zboží> <nabídky> <nabídka> <číslo-položky>4456</číslo-položky> <zájemce>Rice</zájemce> <cena>6000</cena> <datum>5-1-2004</datum> </nabídka> <nabídka> ……… </nabídka> ……… ……… </nabídky> FLWR - dokumenty
FWLR – příklad 1 • Pro každou položku, která má více než deset nabídek, vytvoř element oblíbená-položka s číslem položky, popisem, počtem nabídek for $i in document(“zboží.xml”)/*/položka let $b := document(“nabídky.xml”) /*/nabídka[číslo-položky = $i/číslo-položky] where count($b) > 10 return <oblíbená-položka> { $i/číslo-položky $i/popis <počet-nabídek> { count ($b) } </počet-nabídek> } </oblíbená-položka> ~ SQL: spojení: -dva xml soubory GROUP BY číslo-položky
FWLR – příklad 2 • Vytvoř zprávu obsahující stav nabídek pro různé položky. Označ každou nabídku stavem ‘OK’, ‘příliš málo’, ‘příliš pozdě’ <zpráva o nabídkách> for $I in document (“položky.xml”)/*/položka return <item> { $i/číslo-položky, for $b in document (“nabídky.xml”)/*/nabídka[číslo-položky = $i/číslo-položky] return <nabídka> { $b/zájemce, $b/cena, <stav> { if ($b/datum > $i/datum) then “příliš pozdě” else if ($b-cena < $i/cena) then “příliš málo” else “OK” } </stav> } </nabídka> } </item> </zpráva o nabídkách>
Operace na sekvencích 1 • A union B ~ A u B • A intersect B ~ A n B • A except B ~ A \ B • příklad: document(“a.xml”)//položka[cena > 1000] intersect document(“a.xml”)//položka[datum-výroby > date(“2003-12-1”)] • lépe: predikát1 and predikát2 • sortbysekvence ascending | descending
Operace na sekvencích 2 • Nemá význam kombinovat sekvence uzlů z různých dokumentů • NE: document(”zboží.xml“)//číslo-položky except document(”poptávky.xml“)//číslo-položky • porovnávání identit, které nejsou shodné, různé dokumenty mají různé identity • ANO: for $i in document(”zboží.xml“)//položka where empty( document(”poptávky.xml“) //položka[číslo-položky eq $i/číslo-položky] ) return $i/číslo-položky • porovnání obsahu
Funkce • knihovní funkce - document(), avg(), … • uživatelsky definované funkce: define function nejvyšší_poptávka( element $položka) returns decimal { max(document(“poptávky.xml”)// poptávka[číslo-položky = $položka/číslo-položky]/počet-poptávek ) } • příklad volání nejvyšší_poptávka(document(“zboží.xml”)//položka[číslo-položky = “1234”]) • nemusí být specifikovány typy parametrů ani návratová hodnota
Funkce - možnosti • přetížení jména funkce (overloading) - jen u knihovních fcí - string(), … • proměnný počet parametrů • funkce(element? e, anySimpleType $d ) • funkce(element* e) • funkce(element+ e) • rekurze, nepřímá rekurze define function hloubka( element $e) returns integer { if (empty($e/*)) then 1 else 1 + max (for $c in $e/* return depth($c)) }
Struktura XQuery dotazu • dvě části: • prolog - definice prostředí • přiřazení proměnných, • definice namespace • namespace xyz = ‘http://xien.jikos.cz/eshop’ • default element namespace = ‘...’ • default function namespace = ‘...’ • schema namespace xhtml = ‘…’ • tělo - vyhodnocení dotazu
Typy • atomické typy • definované v XSchema - čísla, řetězce,... - xs:integer, xs: string … • elementy ~ třídy v OOP • typ definován v uživatelském schéma: abc:adresa • klíčová slova: • element • element cena • element of type abc:adresa • attribute • instance of operátor, typeswitch • přetypování: cast, treat • validace - přiřazení typů: funkce validate()
Závěr • funkcionální jazyk s procedurálními prvky (FLWR) • datový model • n-ární tříděný strom (les) s uzly různých „specifikačních“ typů • výrazy cesty (XPath) // ~ /descendant - spojení cesty (path join) • uživatelsky definované funkce • Working Draft W3C XML Working Group Co přináší nového? • Oproti OQL dotaz do větší hloubky + /descendant Co nelze vyjádřit? • Dotaz na podobnost dokumentů • DIS na XML • odvození podobnosti na základě hierchie tříd (typů) definovaných ve schema = RDF Reasonig
XQuery - implementaceXML nativní databáze • X-Hive/DB: http://www.x-hive.com/xquery • Microsoft: http://xqueryservices.com • Cerisent: http://www.cerisent.com/use-cases.html • XML Global: http://www.xmlglobal.com • eXist: http://www.exist.org • Xindice: http://xml.apache.org/xindice
Literatura • 1. D. Chamberlin - XQuery: An XML query language, IBM SYSTEMS JOURNAL, VOL 41, NO 4, 2002, http://www.research.ibm.com/journal/sj/414/chamberlin.pdf • 2. XQuery: A Query Language for XML, W3C, http://www.w3.org/TR/xquery/ • J. Savolskyte - XQuery, 5.6.2002 • A. Eiseinberg - An Early Look at Xquery, IBM, Westford • K. Howard - An Introduction to Xquery, http://www-106.ibm.com/deleveloperworks/xml/library/x-xquery.html • A quick intro to Xquery, http://www.fatdog.com/XQuery_Intro.html
Dotaz • Napište funkci, která přejmenuje názvy podelementů na velká písmena. define function upcaseSubelement(element $e) { for $i in (0, count ($e/*)) return { element { upcase( name( $e[$i])) } { $e/@*, data($e) } } }
Dodatek • Relační databáze a XML • model uložení XML v relační DB • Path join algoritmus • schéma číslování • popis algoritmu (eXist) • Fulltext na XML • XIRQL – XML Information Retrieval Query Language • váhy, relevance, typy • RDF Reasoning
Relační DB a XML <kontakt> <jméno typ=“plné”> Jan Vávra </jméno> <telefon> <doma> 387994840 </doma> <kancelář> 222011256 </kancelář> </telefon> <e-mail> jan.vavra@matfyz.cz </e-mail> </kontakt>
<kontakt> <jméno> Jan Vávra</jméno> <telefon> <doma>387994840 </doma> <kancelář>222011256 </kancelář> </telefon> </kontakt> pro efektivní zjištění rodiče uzlu díry pro přidávání parent(i) = [ (i-2)/k +1 ] k - arita stromu, resp. k(d), arita úrovně d Schéma číslování
Path join – 1/2 • Tříděné seznamy ancestors list al, descendants list dl • get_parent_set( seznam_x) :seznam_x := seznam předků v seznam_x, return false ~ délka nového seznamu 0 al get_parent_set() dl dl dl_orig . . . ? = get_parent_set()
Path join – 2/2 • Algorithm ancestor_descendant_join (al, dl) dl_orig = copy of dl; // get_parent_set() – nahradí každé id uzlu, id jeho rodiče while (get_parent_set(dl)) { ax = 0; dx = 0; while (dx < dl.length) { //některý uzel neměl předka if (dl[dx] = null) dx++; //přejdi na dalšího předka .. ax++ else if (dl[dx] > al[ax]) { if (ax < al.length - 1) ax++; else break; } //přejdi na dalšího přímého předka .. dx++ else if (dl[dx] < al[ax]) dx++; else {//shoda: předek al[ax] je přímý předek dl_orig[dx] output(al[ax], dl_orig[dx]); dx++; }}}
XIRQL – váhy • vážené termy v dokumentu • vážené termy v dotazu ( //položka[ 0.8 * název =“háček“) • v daném kontextovém uzlu (např. //položka) se vyhledává ploše – fulltextovým vyhledáváním s váhami
XIRQL – relevance • podpora tradičních dotazů DIS • nezohledňují strukturu => problém: term v kořeni má menší váhu • zohlednění struktury: • pronásobení číslem < 1 • ? celou cestu, jen jedenkrát
XIRQL–typy • operátory na základě datových typů • např. ‘=‘ pro string, typ operandů zjistí sám strojXIRQL • klasifikační schémata, thesaurus • atributy vs. elementy – to samé
RDF Reasoning • potomci elemenentu jako položky struktury dané elementem • odvozování (reasoning) na základě typů položek třídy • HomePhoneType -> PhoneType class Clovek{ HomeAddressType adresa; HomePhoneType telefon; Integer vek; }
Literatura - dodatek • Systém pro správu a dotazování rozsáhlých slovníků ve formátu XML, Diplomová práce - Josef Kořenek, FI - Masarykova univerzita, Brno 2002, http://nlp.fi.muni.cz/projekty/maxxl2/diplomka/maxxl.pdf • eXist: An Open Source Native XML Database – W. Meier, Darmstadt University of Technology, 2002, http://exist-db.org/webdb.pdf • XIRQL: A Query Language for Information Retrieval in XML Documents – N. Fuhr, Kai Groβjohann, University of Dortmund, 2001 • http://ls6-www.informatik.uni-dortmund.de/bib/fulltext/ir/Fuhr_Grossjohann:02.pdf • http://www.is.informatik.uni-duisburg.de/projects/carmen/2001-09-sigir01.pdf • Jena SemWeb Toolkit, HP Labs, http://jena.sourceforge.net/