5 XML Query Language Skeemojen opiskelun myötä olemme polulla joka luontevasti johtaa ajatukseen XMLdokumenteista tietokantoina. Erityisesti, XML-skeema voi vaatia että tietty rakenne toimii (esiintymässä) avaimen tavoin (xsd: unique, xsd:key/xsd:keyref). Tätä voidaan ilmeisesti hyödyntää esim. kyselyissä. Vaikka myös matalan tason sovellusohjelmointi (SAX, DOM) hyötyy täsmällisistä skeemamäärittelyistä, ei XML-muotoisen tiedon käsittely suoraan ruohonjuuritasolla ole aina tuottavaa (vrt. XSLT vs. DOM). XML-dataan on kuitenkin mahdollista päästä myös XML-kyselykielten välityksellä (vrt. SQL). XML-kyselykieliä on useita erilaisia; rajaamme (suppean!) tarkastelumme seuraavassa XQuery-teknologiaan koska se muodostunee jatkossa de facto - standardiksi (Huom. se ei siis vielä ole esim. W3C-suositus). MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 92
5.1 Välisoitto Tehokas sovellusintegraatio on tiedon saatavuuden näkökulmasta hyvä asia Tiedon yhtenäinen tekninen esitys ja vaivaton saatavuus korostavat myös esim. tietoturvan merkitystä organisaatioissa... tekijänoikeudet, tietosuoja ja rekisterit, yms. MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 93
5.2 Perusidea: XML tietokantana Useat XML-sovellukset voidaan käsitteellisesti jäsentää XML-tietokantoja (database) hyödyntävinä sovelluksina Kuten tietokantajärjestelmien tapauksessa, myös XML-sovellusten suunnittelu selkiytyy kun... - tietoa noudetaan kannasta kyselyiden (query) avulla... - jotka palauttavat XML-dokumentteja... - joita käsitellään hallitusti "matalan tason" rajapintojen avulla (esim. DOM) Huom. Ratkaisu tarjoaa keinon esittää periaatteessa mitä tahansa tietoa (ns. virtual [XML] documents) XML-rajanpinnan läpi (myös olemassa olevia relaatiotietokantoja(!)) XML DOM Application DOM XML Application DB XQuery XML DOM MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 94
5.3 XML Query Language XML Query Language eli XQuery määrittelee kielen jolla DTD:n tai XMLskeeman mukaisesta loogisesta tietovarannosta voidaan tietyn syntaksin puitteissa kysellä tietoa - ks. http://www.w3.org/tr/2005/wd-xquery-20050915/ Kyselykieli pohjautuu vahvasti XPath-tekniikkaan, mikä määrittelee viittausten perustan useissa XML-perheen tekniikoissa (esim. XSLT) - teknisesti: XQuery laajentaa XPath 2.0 -määritystä XPath 2.0 - lausekkeet kelpaat siis jo XQuery-kyselyiksi Itse kysely(lauseke) (query) on tekstimuotoinen lauseke (XPath/XMLsyntaksi) Kysely palauttaa tuloksena (result) XML-elementtirakenteen (ei vaatimusta juurielementistä, ts. voi olla myös hyvin muodostettu XML-tekstientiteetti) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 95
5.4 SQL-tyyppinen esimerkki (1/3) Olkoon annettuna seuraava XML-dokumentti <bib> <book year="1994"> <title>tcp/ip Illustrated</title> <author><last>stevens</last><first>w.</first></author> <publisher>addison-wesley</publisher> <price>65.95</price> </book>... <book year="1992"> <title>advanced Programming in the Unix environment</title> <author><last>stevens</last><first>w.</first></author> <publisher>addison-wesley</publisher> <price>65.95</price> </book> MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 96
... <book year="2000"> <title>data on the Web</title> <author><last>abiteboul</last><first>serge</first></author> <author><last>buneman</last><first>peter</first></author> <author><last>suciu</last><first>dan</first></author> <publisher>morgan Kaufmann Publishers</publisher> <price>39.95</price> </book> </bib> <book year="1999"> <title>the Economics of Technology and Content for Digital TV</title> <editor> <last>gerbarg</last><first>darcy</first> <affiliation>citi</affiliation> </editor> <publisher>kluwer Academic Publishers</publisher> <price>129.95</price> </book> MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 97
5.5 SQL-tyyppinen esimerkki (2/3) Suoritetaan kysely: "List the titles and years of all books published by Addison-Wesley after 1991, in alphabetic order." <bib> (: An example from the test cases [ON] :) { for $b in doc("http://bstore1.example.com/bib.xml")//book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 order by $b/title return <book> { $b/@year } { $b/title } </book> } </bib> Huomioita: - oma syntaksi, XPath-lausekkeita, ns. FLWOR ("flower") -kysely MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 98
5.6 SQL-tyyppinen esimerkki (3/3) Kyselyn tuloksena (result) saadaan odotetusti: <bib> <book year="1992"> <title>advanced Programming in the Unix environment</title> </book> <book year="1994"> <title>tcp/ip Illustrated</title> </book> </bib> Huomioita: - SAX/DOM-ohjelmointiin verrattuna kysely yksinkertaistaa XML:n roolia sovelluksessa - tuloksen käsittelyyn tarvitaan XML-prosessointia, mutta tulos on helppo pakottaa helposti käsiteltävään muottiin (vrt. XML CSV) - tehtävän tasolla, yhtäläisyys XSLT-muunnosten kanssa on ilmeinen MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 99
5.7 XML-tietokannan tietomalli, huomioita SQL-vertauskuva ei kanna määräänsä pidemmälle: on hyvä muistaa että - XML-tietomalli on rakenteeltaan monimutkaisempi kuin relaatio JA - skeemamääritys voi sisältää vaihtoehtoisia ja toistuvia osia Ts. esim. seuraavalle "rikkaalle" tietorakenteelle ei löydy suoraa vastinetta relaatiotietokannoista (joskin "sama tietosisältö" voitaisiin toki esittää toisin): <!ELEMENT bib (book* )> <!ELEMENT book (title, (author+ editor+ ), publisher, price )> <!ATTLIST book year CDATA #REQUIRED > <!ELEMENT author (last, first )> <!ELEMENT editor (last, first, affiliation )> <!ELEMENT title (#PCDATA )> <!ELEMENT last (#PCDATA )> <!ELEMENT first (#PCDATA )> <!ELEMENT affiliation (#PCDATA )> <!ELEMENT publisher (#PCDATA )> <!ELEMENT price (#PCDATA )> MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 100
5.8 XQuery-kielioppi (1/5): perusteet Lausekkeiden perusrakenne, (dokumentin jäsennyspuun) solmun käsite, literaalit ja numeeriset tyypit tulevat XPathista ja XML-skeemoista, esim. doc("bib.xml")/bib//author[1] "merkkijono" -1.3E2 Kyselyn lähde valitaan syötefunktioiden avulla (input functions): - doc(...) (dokumenttisolmu, esim. doc("bib.xml") ) - collection(...) (kokoelma solmuja [listarakenne], esim. fn:collection("http://example.org")//customer ) - collection() valitsee oletussyötteenä oletuskokoelman (default collection) Kyselyn lähde voi olla selvillä myös kontekstin (tai kyselyn esittelyssä ilmoitetun option) perusteella Kyselyn liittyvät kommentit kirjataan hymynotaatiolla (: kommentti :) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 101
5.9 XQuery-kielioppi (2/5): rakentajat Solmuja voidaan tuottaa suoraan rakentajien (constructor) avulla, esim.: <book year="1994"> <title>tcp/ip Illustrated</title> <author><last>stevens</last><first>w.</first></author> <price>65.95</price> </book> Sama voidaan tuottaa ohjelmallisesti myös rakentajakomentojen avulla (ns. computed constructors, vrt. XSLT-komennot), esim.: element book { attribute year { "isbn-0060229357" }, element title { "TCP/IP Illustrated" }, element author { element last { "Stevens" }, element first { "W." } }, element price { 65.95 } } MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 102
5.10 XQuery-kielioppi (3/5): ohjelmointi Aaltosulut merkkaavat evaluoitavan kohdan: <fact>i saw {5 + 3} cats.</fact> (: gives 8 :) XQuery sisältää tyypillisiä ohjelmointikielten piirteitä, kuten silmukoita (käsitellään tuonnempana) ja ehtolauseita: if ($widget1/unit-cost < $widget2/unit-cost) then $widget1 else $widget2 Monimutkaisemmat lausekkeet voidaan suunnitella funktioina: declare function local:between($seq as node()*, $start as node(), $end as node()) as item()* (: The between() function takes a sequence of nodes, a starting node, and an ending node, and returns the nodes between them. :) { let $nodes := for $n in $seq except $start//node() where $n >> $start and $n << $end return $n return $nodes except $nodes//node() }; MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 103
5.11 XQuery-kielioppi (4/5): kyselyt Yksinkertainen kysely palauttaa koko dokumentin sisällön tai sen osan: doc("bib.xml")//book Arkinen kysely rakentaa esim. tulokseen omia elementtejä: suorittaa laskentaa ja vertailuja: <example> <p> Here is a query. </p> <eg> $b/title </eg> (: tekstiä, EI evaluoitava lauseke! :) <p> Here is the result of the query. </p> <eg>{ $b/title }</eg> (: evaluoitava lauseke :) </example> Hieman monimutkaisempi kysely suorittaa myös "ehdollista laskentaa": (: oletetaan että muuttujat $dict ja $e on sidottu sopivasti... :) element {$dict/entry[@word=name($e)]/variant[@xml:lang="it"]} {$e/@*, $e/node()} Ks. http://www.w3.org/tr/2005/wd-xquery-20050915/#id-computedelements MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 104
5.12 XQuery-kielioppi (5/5): kyselyn esittelyosa Kysely voi sisältää myös esittelyosan (prolog) Tyypillinen käyttötapaus on XQuery-version ja kyselyssä tarvittavien nimiavaruuden (prefiksinimien) esittely (declare): xquery version "1.0" encoding "utf-8"; declare namespace p="http://example.com/ns/p"; declare namespace q="http://example.com/ns/q"; declare namespace f="http://example.com/ns/f"; <p:a q:b="{f:func(2)}" xmlns:r="http://example.com/ns/r"/> Kyselyt voidaan jakaa myös useisiin moduuleihin joihin viitata (import): import module namespace math = "http://example.org/math-functions"; Esittelyosa voi lisäksi sisältää esim. muuttujien esittelyjä, (itse määriteltyjä, kukaties rekursiivisiakin) funktioita ja kyselyä ohjaavia asetuksia MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 105
5.13 FLWOR-lausekkeet: sano se kukkasin Kyselyiden tärkeä erikoistapaus ovat FLWOR-kyselyt (for-let-where-order-return), esimerkiksi: for $d in fn:doc("depts.xml")/depts/deptno let $e := fn:doc("emps.xml")/emps/emp[deptno = $d] where fn:count($e) >= 10 order by fn:avg($e/salary) descending return <big-dept> { $d, <headcount>{fn:count($e)}</headcount>, <avgsal>{fn:avg($e/salary)}</avgsal> } </big-dept> Huomaa SQL-tyyppinen rakenne; keskeinen ero on se miten ja mistä syötevirta muodostuu (ns. tuple stream) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 106
5.14 FLWOR-lausekkeiden evaluointi FLWOR-lausekkeiden syntaksi on melko intuitiivinen: FLWORExpr ::= (ForClause LetClause)+ WhereClause? OrderByClause? "return" ExprSingle for- ja let-osat (kenties useita kutakin) iteroivat valitun solmujoukon läpi, kiinnittäen "työmuuttujia" "silmukkamuuttujien" osoittamiin tietorakenteisiin syötevirrassa where-osa suodattaa syötevirtaa (valinnainen) order by -osa järjestää syötevirran (valinnainen) return-osa suoritetaan kerran kutakin (where-osan ehdot täyttävää) syötevirran alkiota kohden MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 107
5.15 FLWOR-lausekkeista (1/3): for Huomaa että for ja let -osat ovat aidosti erilaisia Esimerkki, for -kysely: for $s in (<one/>, <two/>, <three/>) return <out>{$s}</out> Tulos: <out> <one/> </out> <out> <two/> </out> <out> <three/> </out> Ts. return arvioidaan kerran kullekin silmukkamuuttujan arvolle MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 108
5.16 FLWOR-lausekkeista (2/3): let Esimerkki, let -kysely: let $s := (<one/>, <two/>, <three/>) return <out>{$s}</out> Tulos: <out> <one/> <two/> <three/> </out> Ts. return arvioidaan vain kerran (koska ei silmukkaa) for ja let -osia voidaan myös yhdistellä tuloksena on varsin mutkikkaita lauseita (jotka kannattaa yleensä järjestää jotta järjestys olisi määrätty): for $x in $w, $a in f($x) let $y := g($a) for $z in p($x, $y) return q($x, $y, $z) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 109
5.17 FLWOR-lausekkeista (3/3): where ja order Peruskäytössä where-osa suorittaa testin jonka syötevirran alkioiden täytyy läpäistä, esim.... where $u/rating > "C" and $i/reserve_price > 1000 and $i/offered_by = $u/userid... where $i mod 100 = 0... where contains($i/description, "Bicycle")... order -osa puolestaan näyttää esim. tältä: for $e in $employees order by $e/salary descending (: tai esim. ascending empty least :) return $e/name MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 110
5.18 Funktiosta (1/2): itse määritellyt funktiot Esimerkki: "A local function that accepts a sequence of employee elements, summarizes them by department, and returns a sequence of dept elements." declare function local:summary($emps as element(employee)*) as element(dept)* { for $d in fn:distinct-values($emps/deptno) let $e := $emps[deptno = $d] return <dept> <deptno>{$d}</deptno> <headcount> {fn:count($e)} </headcount> <payroll> {fn:sum($e/salary)} </payroll> </dept> }; local:summary(fn:doc("acme_corp.xml")//employee[location = "Denver"]) Funktioiden yhteydessä vaaditaan aina nimiavaruuden käyttöä MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 111
5.19 Funktiosta (2/2): funktiokirjasto XQuery (1.0) hyödyntää laajennettua XPath (2.0) -funktiokirjastoa - ks. http://www.w3.org/tr/xquery-operators/ fn:function-name($parameter-name as parameter-type,...) as return-type Funktioiden käytön perusidea ja syntaksi on sama kuin XPath 1.0:ssa, eroja: - nimiavaruuksien käyttö - funktioiden määrä (!) - XQuery mahdollistaa omien funktioiden määrittelyn (!) XQuery-funktiokirjasto on nyt ilahduttavan laaja, erityisesti: kirjasto sisältää monia XML-skeemojen esimääriteltyjä datatyyppejä käsitteleviä funktioita MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 112
5.20 Esimerkkiprosessori: Saxon XSLT-sovelluksista tuttu Saxon(-B)-prosessori tarjoaa hyvän XQuery-toteutuksen - ks. http://www.saxonica.com/ Olkoon annettuna lähdedokumentti bib.xml ja kysely find.xq, esim. xquery version "1.0" encoding "iso-8859"; <root> <!-- books including string in their title "nt"... --> { for $s in //title where fn:contains($s,"nt") return $s } </root> Komento java -classpath... net.sf.saxon.query -s bib.xml find.xq...suorittaa halutun kyselyn MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 113
5.21 XML-sarjallistus XQuery-kyselyt voidaan esittää myös XML-muodossa (XQueryX), esim.: <bib> { for $b in doc("http://bstore1.example.com/bib.xml")/bib/book where $b/publisher = "Addison-Wesley" and $b/@year > 1991 return <book year="{ $b/@year }"> { $b/title } </book> } </bib> Ks. http://www.w3.org/tr/2005/wd-xqueryx-20050915/#example1...tuloksena 129 riviä koodia(!) Ts. käsin työhön ei tee mieli ryhtyä, mutta mahdollisuus kyselyiden käsittelyyn XML-rajapinnan läpi on toki paikallaan (esim. XSL-muunnoksin) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 114
5.22 Lopuksi, huomioita Relaatiotietokantajärjestelmien suuri suosio perustuu eittämättä abstraktin relaatiotietokanta-kyselykieli -ratkaisumallin yleisyyteen: tietokanta voidaan "löytää" keskeisestä roolista miltei mistä tahansa sovelluksesta XQuery-prosessoreita voidaankin analogisesti pitää yhtenä keskeisimmistä XML-tekniikosta ( XML-kehitystyön tehokkuuden parantuminen) Melko pian huomataan että XQuery ja XSLT-tekniikat ovat tietyssä mielessä melko samanlaisia; tuntuu luonnolliselta olettaa että (iso) osa käyttötapauksista joihin nykyään sovelletaan XSL-muunnoksia voidaan tulevaisuudessa toteuttaa luontevasti XQuery-kyselyinä (funktiot & lausekielinen ohjelmointi...) Kuten XML-skeemojen, myös XQuery-teknologian opiskeluun voisi perustellusti käyttää lyhyen peruskurssin verran aikaa asiaa ei varmasti opi yksinomaan pinnallisesta esittelystä (vaan tekemälläpä oppii) MATHM-57200 RAKENTEISTEN DOKUMENTTIEN JATKOKURSSI (syksy 2005) - ON 115