XML/XQuery
- Comprendere che cos'è XQuery e quali sono le differenze con XPath e XSLT
- Saper usare le espressioni XQuery
XQuery è un linguaggio di query sviluppato dal World Wide Web Consortium (W3C) e consente di estrarre in modo efficiente e semplice informazioni da database XML nativi e database relazionali che archiviano dati XML.
Ogni query è costituita da un'introduzione e un corpo. L'introduzione stabilisce l'ambiente in fase di compilazione, ad esempio le importazioni di schemi e moduli, le dichiarazioni di namespace e funzioni, e le funzioni definite dall'utente. Il corpo genera il valore dell'intera query. La struttura di XQuery è nella tabella qui sotto:
Introduzione | Commento: | (: Sample version 1.0 :)
|
Dichiarazione del namespace: | declare namespace my = "urn:foo";
| |
Dichiarazione di funzione: | declare function my:fact($n) {
if ($n < 2)
then 1
else $n * my:fact($n – 1)
};
| |
Variabile globale: | declare variable $my:ten {my:fact(10)};
| |
Corpo | Costrutto XML | <table>
|
Espressione FLWOR: | for $i in 1 to 10
return
| |
Espressione contenuta: | <tr>
<td>10!/{$i}! = {$my:ten div my:fact($i)} </td>
</tr>
} </table>
|
Confronto tra XQuery e XPath e XSLT
modificaXQuery, XPath, XSLT e SQL sono linguaggi di query di buona qualità. Ognuno di questi linguaggi ha i propri vantaggi a seconda delle situazioni, quindi XQuery non può sostituirli in ogni attività. XQuery si basa su espressioni XPath. XQuery 1.0 e XPath 2.0 condividono lo stesso modello di dati, le stesse funzioni e la stessa sintassi. Nella tabella vengono illustrati i vantaggi e gli svantaggi di ogni linguaggio di query.
Vantaggio | Svantaggio | |
---|---|---|
Xquery |
|
Le implementazioni di XQuery sono meno mature di quelle XSLT |
XPath 1.0 |
|
|
XSLT 1.0 |
|
|
XQuery presenta analogie con SQL sia nello stile che nella sintassi. La differenza principale tra XQuery e SQL è che SQL si concentra su set non ordinati di righe "flat", mentre XQuery si concentra su sequenze ordinate di valori e nodi gerarchici.
Espressioni XQuery
modificaEspressioni FLWOR
modificaLe espressioni FLWOR sono una parte importante di XQuery. FLWOR è pronunciato come la parola inglese flower. Questo nome deriva dalle clausole FOR, LET, WHERE, ORDER BY e RETURN con cui sono organizzate le espressioni. Le clausole FOR e LET possono risultare un numero qualsiasi di volte in qualsiasi ordine. Le clausole WHERE e ORDER BY sono facoltative. Tuttavia, queste clausole devono essere visualizzate nell'ordine indicato se vengono utilizzate. La clausola RETURN deve esistere.
XQuery consente di utilizzare le query di join in modo simile a SQL. Questo esempio illustra una query di join tra la tabella die video e la tabella degli attori.
let $doc := .
for $v in $doc//video,
$a in $doc//actors/actor
where ends-with($a, 'Lisa')
and $v/actorRef = $a/@id
order by $v/year
return $v/title
La clausola LET indica l'assegnazione di una variabile. In questo caso, la query la inizializza su documento videos.xml, oppure il risultato di una query inserisce un documento in un database. La clausola FOR descrive un meccanismo per l'iterazione: una variabile elabora tutti i video a sua volta, un'altra variabile elabora tutti gli attori a sua volta. In questo caso, la query elabora le coppie di video e attori. La clausola WHERE consente di selezionare le tabelle a cui si è interessati. In questo caso, si desidera sapere che l'attore con il nome che termina con "Lisa" venga visualizzato nella tabella video. La clausola ORDER BY restituisce i risultati in un ordine dato. In questo caso, si desidera avere un risultato con i video in ordine di data di rilascio. La clausola RETURN alla fine di un'espressione informa il sistema di quali informazioni si desidera ottenere. In questo caso, si desidera il titolo del video.
Espressione condizionale
modificaXQuery offre le espressioni condizionali con le clausole IF, THEN e ELSE. La clausola ELSE è obbligatoria: ogni espressione in XQuery deve restituire un valore. Nell'esempio qui sotto viene mostrata una query per recuperare tutti i libri e i relativi autori. Si desidera restituire gli altri autori dopo i primi due come "et-al".
for $b in document("books.xml")/bib/book
return
if (count($b/author) <= 2) then $b
else <book> { $b/@*, $b/title, $b/author[position() <= 2], <et-al/>,
...... $b/publisher, $b/price } </book>
Questa query legge i dati del libro da un file books.xml. Se il numero di autori è minore di 2 o uguale a 2 per ogni libro, la query restituisce direttamente il libro. In caso contrario, la query crea un nuovo elemento book includendo tutti i dati originali, ad eccezione del fatto che la query contiene solo i primi due autori e associa un elemento et-al. La funzione Position()
viene restituita solo ai primi due autori. L'espressione XPath $b/@*
fa riferimento a tutti gli attributi di $b.
Funzioni e operatori XQuery
modificaXQuery contiene un enorme set di funzioni e operatori. La tabella mostra le funzioni predefinite utilizzate più di frequente. È possibile costruire le proprie funzioni, e molti motori forniscono anche estensioni personalizzate.
Funzione | Commento |
---|---|
Matematica: +, -, *, div, idiv, mod, =, !=, <, >, <=, >= floor(), ceiling(), round(), count(), min(), max(), avg(), sum() |
La divisione viene eseguita utilizzando div anziché una barra perché una barra indica un'espressione di passaggio XPath. idiv è un operatore speciale per la divisione solo tra interi che restituisce un numero intero e ignora qualsiasi resto.
|
Stringhe ed espressioni regolari: compare(), concat(), starts-with(), ends-with(), contains(), substring(), string-length(), substring-before(), substring-after(), normalize-space(), upper-case(), lower-case(), translate(), matches(), replace(), tokenize() |
compare() detta l'ordinamento delle stringhe. translate() esegue una mappatura speciale di caratteri. match() , replace() e tokenize() usano espressioni regolari per trovare, manipolare e dividere i valori di stringa.
|
Data e ora: current-date(), current-time(), current-dateTime() +, -, div eq, ne, lt, gt, le, gt |
XQuery ha molti tipi speciali per i valori di data e ora come duration, dateTime, date e time. Nella maggior parte dei casi è possibile eseguire operatori aritmetici e di confronto come se fossero numerici. Le abbreviazioni di due lettere indicano uguale, non uguale, minore di, maggiore di, minore di o uguale e maggiore di o uguale. |
Nodi XML e QNames: node-kind(), node-name(), base-uri() eq, ne, is, isnot, get-local-name-from-QName(), get-namespace-from-QName() deep-equal() >>, << |
node-kind() restituisce il tipo di nodo (ovvero "elemento"). node-name() restituisce il QName del nodo, se esiste. base-uri() restituisce l'URI da cui proviene questo nodo. I valori di nodi e QName possono anche essere confrontati usando eq e ne (per il confronto di valori), oppure is e isnot (per il confronto di identità). deep-equal() confronta due nodi in base al loro contenuto ricorsivo completo. L'operatore << restituisce true se l'operando di sinistra precede l'operando di destra nell'ordine del documento. L'operatore >> è un confronto seguente.
|
Sequenze: item-at(), index-of(), empty(), exists(), distinct-nodes(), distinct-values(), insert(), remove(), subsequence(), unordered().position(), last() |
item-at() restituisce un item in una data posizione mentre index-of() tenta di trovare una posizione per un dato. item.empty() restituisce true se la sequenza è vuota ed exists() restituisce true in caso contrario. dictinct-nodes() restituisce una sequenza con nodi esattamente identici che sono stati rimossi e distinct-values() restituisce una sequenza con eventuali valori atomici duplicati rimossi. unordered() consente al motore di ottimizzare la query senza preservare l'ordine. position() restituisce la posizione dell'elemento di contesto attualmente in elaborazione. last() restituisce l'indice dell'ultimo elemento.
|
Tipo di conversione: string(), data(), decimal(), boolean() |
Queste funzioni restituiscono il nodo come il tipo specificato, ove possibile. data() restituisce il "valore digitato" del nodo.
|
Booleani: true(), false(), not() |
Non ci sono parole chiave "true" o "false" in XQuery ma piuttosto funzioni true() e false() . not() restituisce la negazione booleana del suo argomento.
|
Input: document(), input(), collection() |
document() restituisce un documento di nodi basato su un parametro URI. collection() restituisce una raccolta basata su un parametro stringa (forse più documenti). input() restituisce il set di nodi di input fornito dal motore generale.
|
Bibliografia
modifica- Jason Hunter, X Is for XQuery
- Michael Kay, An Introduction to the XQuery FLWOR Expression
- Michael Kay, Learn XQuery in 10 Minutes
- Michael Brundage, XQuery: The XML Query Language, Addison-Wesley 2004
Collegamenti esterni
modifica- W3C XML Query (XQuery)
- XQuery Latest version
- XQuery 1.0 and XPath 2.0 Functions and Operators
- XQuery 1.0 and XPath 2.0 Data Model (XDM)
- XSLT 2.0 and XQuery 1.0 Serialization
- XML Query Use Cases
- XML Query (XQuery) Requirements