Basi di dati in XML
Possiamo rappresentare le basi di dati con documenti XML strutturati secondo regole in documenti schema-specification. Il linguaggio XML è detto semistrutturato perché i suoi nodi possono contenere un numero arbitrario di figli. In questa lezione si dà per conosciuta la sintassi dei documenti XML (si veda la lezione XML).
Oggi XML è usato nell'ambito delle basi di dati principalmente come strumento di scambio di dati tra sistemi non compatibili. Convertire i dati dal proprio formato a XML permette di rendere le informazioni accessibili anche da altri sistemi (a patto, ovviamente, che siano in grado di interpretare XML). La rapida diffusione di XML nata con internet, è dovuta alla sua semplicità e flessibilità, che permette di strutturare i dati in modo gerarchico ma completamente indipendente dal software e dall'hardware usato, in quanto conservato in semplici file di testo.
Linguaggi di interrogazione
modificaI linguaggi di interrogazione o query language sono linguaggi utilizzati per interrogare una base di dati, nel nostro caso per estrarre dati dai documenti XML.
XPath
modificaXPath è stato creato dal W3C nel 1999 (versione 1.0) per essere utilizzato con XSLT e successivamente aggiornato alle versioni 2.0 (2004) e 3.0 (2014). Espressioni utilizzate in XPath:
espressione | significato |
---|---|
nodo | Seleziona tutti i figli del nodo indicato |
/ | Seleziona dal nodo radice |
// | Seleziona dal nodo corrente in tutto il documento |
. | Seleziona il nodo corrente |
.. | Seleziona il padre del nodo corrente |
@ | Seleziona gli attributi |
Spieghiamo con degli esempi XPath. Esempio: sia scuola.xml:
<root>
<class name="4B">
<teacher>Elena Premi</teacher>
<student>Mario Rossi</student>
<student>Ilaira Brambilla</student>
<student>Mario Bianchi</student>
...
</class>
<class name="5B">
<teacher>Alessandro Selo</teacher>
<student>Mario Neri</student>
<student>Luca Bianchi</student>
...
</class>
</root>
Allora le query:
- ritornerà:
doc("scuola.xml")/root/class
<class name="4B">
<teacher>Elena Premi</teacher>
<student>Mario Rossi</student>
<student>Ilaira Brambilla</student>
<student>Mario Bianchi</student>
...
</class>
<class name="5B">
<teacher>Alessandro Selo</teacher>
<student>Mario Neri</student>
<student>Luca Bianchi</student>
...
</class>
- ritornerà:
doc("scuola.xml")/root/class[2]
<class name="5B">
<teacher>Alessandro Selo</teacher>
<student>Mario Neri</student>
<student>Luca Bianchi</student>
...
</class>
- ritornerà:
doc("scuola.xml")/root/class[teacher="Alessandro Selo"]/student
<student>Mario Neri</student>
<student>Luca Bianchi</student>
...
Sottoelementi
modificaÈ possibile estrarre tutti i sottoelementi indipendentemente dal loro livello. Ad esempio se vogliamo estrarre tutti gli studenti della scuola:
doc("scuola.xml")//student
otterremo:
<student>Mario Rossi</student>
<student>Ilaira Brambilla</student>
<student>Mario Bianchi</student>
<student>Mario Neri</student>
<student>Luca Bianchi</student>
Predicati
modificaI predicati si utilizzano per trovare un nodo specifico secondo alcune condizioni e proprietà del nodo cercato. Possiamo suddividerle in:
- ottiene il secondo libro che compare in ordine in scaffale
doc("libreria.xml")/scaffale/libro[2]
- ottiene l'ultimo libro in scaffale
doc("libreria.xml")/scaffale/libro[last()]
- ottiene i primi 3 libri in scaffale
doc("libreria.xml")/scaffale/libro[position()<4]
- estrae i libri con meno di 200 pagine (dove pagine è un attributo di libro. Se non è presente l'operatore, ad esempio libro[@pagine] si indica che l'attributo esiste o meno)
doc("libreria.xml")//libro[@pagine<200]
XQuery
modificaXQuery è un linguaggio diventato standard W3C che fornisce un metodo per interrogare basi di dati XML, similmente a come SQL interroga basi di dati relazionali. Utilizza una sintassi simile a XPath per definire espressioni di ricerca.
Le XQuery sono costituite dalle espressioni FLWOR (For-Let-Where-OrderBy-Return), la cui sintassi base è:
for $var1 in doc(...)/.../...
return $var1
Questa espressione assomiglia a un foreach nei comuni linguaggi di programmazione; il for cicla su tutti gli elementi dell'array (nel nostro caso tutti i tag ritornati da doc(..)...) ed esegue le istruzioni sottostanti (nel nostro caso ritornando semplicemente tutti gli elementi).
Si possono anche costruire nuovi elementi. Ad esempio, sfruttando l'esempio della libreria:
for $book in doc("libreria.xml")/scaffale/book[@prestato="yes"]
let $booksPrestati := $book
return <libriPrestati> {$booksPrestati} </libriPrestati>
Abbiamo introdotto un nuovo costrutto: let permette di creare nuove variabile e aggregare i dati del for. Se avessimo messo $book direttamente nel return, avremmo ottenuto un tag <libriPrestati> per ogni libro e non uno per tutti. Il risultato di questa query sarà:
<libriPrestati>
<book prestato="yes"><title>Il nome della rosa</title> ... </book>
<book prestato="yes"><title>Il codice da Vinci</title> ... </book>
...
</libriPrestati>
Similmente a SQL possiamo usare clausole where con dati aggregati (si noti che per i dati non aggregati si possono utilizzare semplicemente le condizioni di XPath). Ad esempio se vogliamo ottenere tutti gli scaffali con più di 10 libri ordinati per id:
for $scaffale in doc("libreria.xml")/scaffale
let $books := $scaffale/book
where count($books) > 5
order by $scaffale/@id
return $scaffale
Database relazionali e XML
modificaAlcuni DBMS relazionali supportano anche il formato XML dei dati. In questo caso essi di norma accettano sia i linguaggi di interrogazione SQL sia quelli di XML (come XQuery). I dati vengono comunque gestiti come relazioni e la parte di XML è visibile solo in fase di presentazione delle informazioni.
In base alla tecnologia scelta, il formato del documento XML può essere fisso rispetto a un DTD, variabile consegnando il DTD con l'XML oppure ricostruito a discrezione del DBMS.