XQuery
Transcript
XQuery
;4XHU\ XQuery Il linguaggio XQuery è lo standard adottato dal W3C per la manipolazione e ristrutturazione di documenti XML. XML - Consente di iterare sugli elementi di un documento - Consente di ristrutturare i contenuti XML XQuery assieme ad XPath costituisce un query language completo (detto anche XML Query) per l’interrogazione di dati in formato XML. XML Deriva dalla rielaborazione e sintesi di vari linguaggi precedentemente proposti (es. XML-QL, YATL, Lorel, Quilt). XQuery - interrogazioni Una interrogazione XQuery è composta di quattro parti: 1. La clausola for: consente di dichiarare variabili che permettono di iterare sugli elementi contenuti in un documento 2. La clausola let: consente la dichiarazione di nuove variabili, eventualmenet correlate a quelle introdotte nella clausola for 3. La clausola where: consente di esprimere predicati per la selezione degli elementi che compongono il risultato dell’interrogazione 4. La clausola return: consente di definire il contenuto e la forma del risultato Per questa forma, le interrogazioni XQuery sono anche dette espressioni FLRW (si legge “flower”: For-Let-Where-Return). Fra la clausola where e la clausola return, ci può stare anche una clausola order per ottenere l’ordinamento del risultato. Interrogazioni XQuery (1) File bib.xml <bib> <book> <title> t1 </title> <author> a1 </author> <author> a2 </author> </book> <paper> <title> t2 </title> <author> a3 </author> <author> a4 </author> </paper> <book> <title> t3 </title> <author> a5 </author> <author> a6 </author> <author> a7 </author> </book> </bib> for $x in document(“bib.xml”)//title return $x 1) La clausola for dichiara la variabile $x 2) I valori che la variabile $x assume sono definiti dalla path expression: document(“bib.xml”)//title che si lega a tutti gli element title contenuti (ovunque) all’interno del doumento bib.xml 3) La successiva clausola return specifica che in questo caso il risultato richiesto coincide con i valori assunti dalla variabile $x <title> t1 </title> <title> t2 </title> <title> t3 </title> Interrogazioni XQuery (2) File bib.xml <bib> <book> <title> t1 </title> <author> a1 </author> <author> a2 </author> </book> <paper> <title> t2 </title> <author> a3 </author> <author> a4 </author> </paper> <book> <title> t3 </title> <author> a5 </author> <author> a6 </author> <author> a7 </author> </book> </bib> for $x in document(“bib.xml”)//title return <TITOLO>{ $x/text() }</TITOLO> Per racchiudere i valori restituiti all’interno di una nuova coppia di TAG, è sufficiente modificare la clausola return L’espressione { $x/text() } estrae il contenuto testuale degli element che si legano alla variabile $x Un’espressione come: <TITOLO>{ $x/text() }</TITOLO> prende il nome di “costruttore di elementi” (il risultato dipende da elementi XML fissi e dal valore di variabili o espressioni) <TITOLO> t1 </TITOLO> <TITOLO> t2 </TITOLO> <TITOLO> t3 </TITOLO> Interrogazioni XQuery (3) File bib.xml <bib> <book> <title> t1 </title> <author> a1 </author> <author> a2 </author> </book> <paper> <title> t2 </title> <author> a3 </author> <author> a4 </author> </paper> <book> <title> t3 </title> <author> a5 </author> <author> a6 </author> <author> a7 </author> </book> </bib> for $x in document(“bib.xml”)//book for $y in $x/author return $y Le espressioni for possono essere annidate In questo caso, la variabile $y fa uso dei valori che si legano alla variabile $x Al ciclo esterno $x assume come valori, uno alla volta, gli element di tipo book Al ciclo interno, per ciascun book legato ad $x, $y assume come valori, uno alla volta, gli element di tipo author contenuti nel book che rappresenta il valore corrente di $x <author> <author> <author> <author> <author> a1 a2 a5 a6 a7 </author> </author> </author> </author> </author> Interrogazioni XQuery (4) File bib.xml <bib> <book> <title> t1 </title> <author> a1 </author> <author> a2 </author> </book> <paper> <title> t2 </title> <author> a3 </author> <author> a4 </author> </paper> <book> <title> t3 </title> <author> a5 </author> <author> a6 </author> <author> a7 </author> </book> </bib> for $x in document(“bib.xml”)//book let $y := $x/author return $y Lo stesso risultato può essere ottenuto anche attraverso un’altra forma di query che utilizza la clausola let In questo caso, alla variabile $y viene assegnato come valore l’insieme degli element author del book legato di volta in volta alla variabile $x <author> <author> <author> <author> <author> a1 a2 a5 a6 a7 </author> </author> </author> </author> </author> Interrogazioni XQuery (5) File bib.xml <bib> <book year=“2003”> <title> t1 </title> <author> a1 </author> <publisher> p1 </publisher> </book> <book year=“2002”> <title> t2 </title> <author> a1 </author> <author> a3 </author> <publisher> p1 </publisher> </book> <book year=“2004”> <title> t3 </title> <author> a2 </author> <author> a4 </author> <author> a7 </author> <publisher> p2 </publisher> </book> </bib> for $x where and return in document(“bib.xml”)//book $x/@year>“2002” $x/publisher=“p1” $x La clausola where (come in SQL) consente di esprimere condizioni di selezione sugli element legati alla variabile $x <book year=“2003”> <title> t1 </title> <author> a1 </author> <publisher> p1 </publisher> </book> Interrogazioni XQuery (6) File bib.xml <bib> <book year=“2003”> <title> t1 </title> <author> a1 </author> <publisher> p1 </publisher> </book> <book year=“2002”> <title> t2 </title> <author> a1 </author> <author> a3 </author> <publisher> p1 </publisher> </book> <book year=“2004”> <title> t3 </title> <author> a2 </author> <author> a4 </author> <author> a7 </author> <publisher> p2 </publisher> </book> </bib> Lo stesso risultato poteva anche essere ottenuto in questo caso senza usare la clausola where, sfruttando XPath per la selezione for $x in document(“bib.xml”)//book[ @year>“2002” and publisher=“p1” ] return $x Interrogazioni XQuery (7) File bib.xml <bib> <book year=“2003”> <title> t1 </title> <author> a1 </author> <publisher> p1 </publisher> </book> <book year=“2002”> <title> t2 </title> <author> a1 </author> <author> a3 </author> <publisher> p1 </publisher> </book> <book year=“2004”> <title> t3 </title> <author> a2 </author> <author> a4 </author> <author> a7 </author> <publisher> p2 </publisher> </book> </bib> for $x in document(“bib.xml”)//book order by $x/@year return $x/title La clausola order by (come in SQL) consente di ordinare il risultato in base ai valori presenti in un qualche componente del risultato <title> t2 </title> <title> t1 </title> <title> t3 </title> Altri esempi (join) XQuery consente di esprimere anche query molto complesse, che coinvolgono join (fra componenti di uno stesso documento XML o di documenti XML diversi), funzioni, aggregati, etc. for $x in document(“bib.xml”)//author let $y := document(“bib.xml”)//book[author=$x] where count($y)>5 return $x Restituisce (come element) i nomi degli autori che hanno scritto almeno 6 libri for $p in document("www.finanze.it/contribuenti.xml")//persona for $n in document("vicini-di-casa.xml")//vicino[CF = $p/CF] return <persona> <codice-fiscale> { $p/CF } </codice-fiscale> { $n/nome } <reddito> { $p/imponibile } </reddito> </persona> Esegue un join sul CF fra i dati in contribuenti.xml e in vicini-di-casa.xml Altri esempi (query complesse) for $d in document("depts.xml")//deptno let $e := document("emps.xml")//employee[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> } </big-dept> 1. La clausola for genera una lista ordinata di element deptno che si legano a $d 2. La clausola let associa ad ogni binding di d$ un ulteriore binding della lista di element emp aventi il numero di dipartimento uguale a $e 3. A questo punto, abbiamo una lista ordinata di tuple di bindings: ($d,$e) 4. La clausola where filtra la lista in modo da ritenere soltanto le tuple desiderate (ossia quelle per cui il numero degli $e vale almeno 10, ossia seleziona i soli dipartimenti in cui lavorano almeno 10 impiegati) 5. La clausola order ordina il risultato in base ai valori decrescenti dello stipendio medio degli impiegati $e che lavorano nei dipartimenti selezionati 6. La clausola return costruisce per ogni tupla un risultato finale opportunamente formattato in XML Es : <big-dept> <deptno> d6 </deptno> <headcount> 230 </headcount> <avgsal> 1425.20 </avgsal> </big-dept>