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>