Indice del libro

Obiettivi di apprendimento

  • 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

modifica

XQuery, 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
  1. esprimere join e sort
  2. manipolazione di sequenze di valori e nodi in ordine arbitrario
  3. facilità di scrivere funzioni definite dall'utente, comprese quelle ricorsive
  4. consente agli utenti di costruire risultati XML temporanei nel bel mezzo di una query, e quindi di navigare in essa
Le implementazioni di XQuery sono meno mature di quelle XSLT
XPath 1.0
  1. sintassi conveniente per l'indirizzamento di parti di un documento XML
  2. selezione di un nodo da un database o un documento XML esistente
  1. impossibile creare nuovo XML
  2. impossibile selezionare solo una parte di un nodo XML
  3. impossibile introdurre variabili o namespace
  4. non può lavorare con i valori di data, calcolare il massimo di un set di numeri o ordinare un elenco di stringhe
XSLT 1.0
  1. elaborazione ricorsiva di un documento XML o traduzione di XML in HTML e testo
  2. creazione di nuovo XML o parte dei nodi esistenti
  3. introduzione di variabili e namespace
  1. non può essere indirizzato senza creare in modo efficace un linguaggio come XQuery
  2. non funziona con sequenze di valori

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

modifica

Espressioni FLWOR

modifica

Le 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

modifica

XQuery 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

modifica

XQuery 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

Collegamenti esterni

modifica