I Dati
biblioteca:
contiene piu’ libro e schede prestito
libro: identificato da un codice univoco, presenta un titolo, un autore formato
da nome e cognome, un editore ed alcune parole chiave. Inoltre mantiene il tipo
di carta su cui e’ stampato (normale, lucida, patinata, riciclata)
Prestito: prevede un utente che ha ricevuto in prestito un certo libro
identificato dal suo codice
Secondo il modello Relazionale
I dati relativi ai Libri
“R414” , “normale” , “2001: Odissea nello spazio” , “Clarke” , “Arthur Charles” , “Rizzoli” , “romanzo” ,
fantascienza”
“Z096” , “normale” , “Io Robot” , “Asimov” , “Isaac” , “Mondadori” , “fantascienza”
“A438” , “lucida” , “Promessi Sposi” , “Manzoni” , “Alessandro” , “Mondadori” , “romanzo”, “storico”
I dati relativi ai Prestiti dei Libri
“A438” , “Damon” , “Crudelia” ,
“Z096” , “Ghini” , “Vittorio” ,
I dati saranno mantenuti in un documento XML.
Il formato XML prevede di organizzare la struttura dei dati in forma gerarchica,
in forma di albero, in cui ogni nodo dell’albero (quelli in nero) e’ un elemento
del documento XML
Quelle che nel modello relazionale sono gli identificatori univoci dei record, e
le chiavi esterne, nel modello XML possono essere realizzate mediante gli
“attributi” dei nodi (in clore rosso) per i quali e’ permesso di specificare
alcuni vincoli.
biblioteca
libro
libro
codice tipocarta titolo autore editore
nome
cognome
libro
parola_
chiave
prestito
parola_
chiave
prestito
prestito
codicelibro utente
nome
cognome
Struttura e componenti di un documento XML
Un documento XML è composto da tre parti:
•
Dichiarazione XML, serve a specificare la versione del linguaggio XML usato
•
Dichiarazione della Struttura del Documento, che e’ opzionale, può anche
essere contenuta in un file esterno, ed è esprimibile in due diversi
linguaggi:
o
Document Type Definition (DTD), piu’ semplice da esprimere e da capire,
non permette pero’ di esprimere requisiti complicati.
o
XML-Schema, linguaggio ottenuto da XML, parecchio complicato ma potente,
perchè permette di descrivere strutture e requisiti molto complessi
Inizialmente utilizzeremo solo DTD, per cominciare ad usare e navigare
documenti XML, successivamente descriveremo ed utilizzeremo anche XML-Schema
•
Contenuto del Documento (con i tag di markup), sono i dati veri e propri del
documento, integrati con i tag del linguaggio, per separare ed identificare
le diverse componenti.
Il contenuto del documento e’ formato da diversi componenti, che sono:
Elementi - Gli elementi sono le parti di documento dotate di un senso proprio.
Il titolo, l’autore, i paragrafi del documento sono tutti elementi. Un elemento
è individuato da un tag iniziale, un contenuto ed un tag finale.
Non confondere i tag con gli elementi!
<titolo>Tre uomini in barca</titolo>
Attributi - Gli attributi sono informazioni aggiuntive sull’elemento che non
fanno effettivamente parte del contenuto (meta-informazioni). Essi sono posti
dentro al tag iniziale dell’elemento. Tipicamente hanno la forma nome=valore
<libro codice=“A438”>…</libro>
Entità - Le entità sono frammenti di documento memorizzati separatamente e
richiamabili all’interno del documento. Esse permettono di riutilizzare lo
stesso frammento in molte posizioni garantendo sempre l’esatta corrispondenza
dei dati, e permettendo una loro modifica semplificata.
&FV;
#PCDATA - Rappresenta il contenuto vero e proprio del documento. Esso
corrisponde alle parole, gli spazi e la punteggiatura che costituiscono il testo.
Viene anche detto #PCDATA (Parsed Character DATA) perché XML usa questo nome per
indicare il contenuto di elementi di testo.
Commenti - I documenti XML possono contenere commenti, ovvero note da un autore
all’altro, da un editore all’altro, ecc. Queste note non fanno parte del
contenuto del documento, e le applicazioni XML li ignorano. Sono molto comodi
per passare informazioni tra un autore e l’altro, o per trattenere informazioni
per se stessi, nel caso le dimenticassimo.
<!--Questa parte è ignorata da XML -->
text - E’ importante notare come gli elementi semplici, ovvero gli elementi
composti da un tag iniziale, un tag finale, ed una stringa testuale (il
contenuto dell’elemento), vengono considerati dal parser XML come dei nodi in
cui esiste un figlio di tipo text, e questo figlio e’ la proprio quella stringa
di testo. Quindi, la selezione della stringa testuale puo’ essere fatta mediante
la sintassi seguente:
child::text()
Il documento XML
<? xml version=”1.0” ?>
<!DOCTYPE biblioteca SYSTEM "biblioteca.dtd" >
<biblioteca>
<libro codice=”R414” tipocarta=”normale” >
<titolo>2001: Odissea nello spazio</titolo>
<autore>
<cognome>Clarke</cognome>
<nome>Arthur Charles</nome>
</autore>
<editore>Rizzoli</editore>
<parola_chiave>romanzo</parola_chiave>
<parola_chiave>fantascienza</parola_chiave>
</libro>
<libro codice=”Z096” tipocarta=”normale”>
<titolo>2001: Io Robot</titolo>
<autore>
<cognome> Asimov </cognome>
<nome> Isaac </nome>
</autore>
<editore>Mondadori</editore>
<parola_chiave>fantascienza</parola_chiave>
</libro>
<libro codice=”A438” tipocarta=”lucida” >
<titolo> Promessi Sposi</titolo>
<autore>
<cognome> Alessandro </cognome>
<nome> Manzoni </nome>
</autore>
<editore>Mondadori</editore>
<parola_chiave>romanzo</parola_chiave>
<parola_chiave>storico</parola_chiave>
</libro>
<prestito codicelibro=”A438”>
<utente>
<cognome> Crudelia </cognome>
<nome> Damon </nome>
</utente>
</prestito>
<prestito codicelibro=”Z096”>
<utente>
<cognome> Ghini </cognome>
<nome> &V; </nome>
</utente>
</prestito>
</biblioteca>
--------------------------------------------------------------------------------------------------Dichiarazione XML, la parte indispensabile con la dichiarazione della versione del linguaggio XML usato
<?xml version=”1.0”?>
--------------------------------------------------------------------------------------------------Document Type Definition (DTD)
<!DOCTYPE biblioteca [
<!ELEMENT biblioteca (libro+ , prestito*)>
<!ELEMENT libro (titolo, autore+, editore, parola_chiave+)>
<!ATTLIST libro codice
ID
#REQUIRED
tipocarta CDATA “normale”
>
<!ELEMENT titolo (#PCDATA)>
<!ELEMENT autore (cognome, nome)>
<!ELEMENT editore (#PCDATA)>
<!ELEMENT parola_chiave (#PCDATA)>
<!ELEMENT cognome (#PCDATA)>
<!ELEMENT nome (#PCDATA)>
<!ELEMENT prestito (utente)>
<!ATTLIST prestito codicelibro IDREF #REQUIRED>
<!ELEMENT utente (cognome, nome)>
<!ENTITY V “Vittorio“ )>
]>
Univocità degli Identificativi ID
In un documento non possono esistere due attributi di tipo ID che assumono lo stesso valore.
Ovvero, definiti cosi’ gli attributi codice ed etichetta come identificatori di tipo ID
<!ATTRLIST libro codice ID #REQUIRED>
<!ATTRLIST barattolo etichetta ID #REQUIRED>
allora due righe come queste di seguito non sono ammesse in uno stesso documento.
<libro codice=”96”>
…….
<barattolo etichetta=”96”>
ERRATO
Integrita’ Referenziale
Se in un documento definisco un attributo di tipo IDREF allora questo deve assumere il
valore di un attributo ID gia’ esistente nello stesso documento.
<!ATTRLIST libro codice ID #REQUIRED>
<!ATTRLIST prestito codicelibro IDREF #REQUIRED>
Affinché codicelibro assuma valore 96 e’ necessario che uno ed uno solo attributo di tipo ID,
nel documento stesso, assuma valore 96.
<libro codice=”96”>
…….
<prestito codicelibro=”96”>
<?xml version="1.0"?>
<!DOCTYPE biblioteca [
<!ELEMENT biblioteca (libro+,prestito*) >
<!ELEMENT libro (titolo, autore+, editore, parola_chiave) >
<!ATTLIST libro codice ID #REQUIRED
tipocarta CDATA "normale"
>
<!ELEMENT titolo (#PCDATA) >
<!ELEMENT autore (cognome,nome) >
<!ELEMENT editore (#PCDATA) >
<!ELEMENT parola_chiave (#PCDATA) >
<!ELEMENT cognome (#PCDATA) >
<!ELEMENT nome (#PCDATA) >
<!ELEMENT prestito (utente) >
<!ATTLIST prestito codice ID #REQUIRED >
<!ELEMENT utente (cognome,nome) >
]>
<biblioteca>
<libro codice="R414" tipocarta="normale">
<titolo>2001: Odissea nello spazio</titolo>
<autore>
<cognome>Clarke</cognome>
<nome>Arthur Charles</nome>
</autore>
<editore>Rizzoli</editore>
<parola_chiave>romanzo</parola_chiave>
<parola_chiave>fantascienza</parola_chiave>
</libro>
<libro codice="Z096" tipocarta="normale">
<titolo>Io Robot</titolo>
<autore>
<cognome>Asimov</cognome>
<nome>Isaac</nome>
</autore>
<editore>Mondadori</editore>
<parola_chiave>fantascienza</parola_chiave>
</libro>
<libro codice="A438" tipocarta="lucida">
<titolo>Promessi Sposi</titolo>
<autore>
<cognome>Manzoni</cognome>
<nome>Alessandro</nome>
</autore>
<editore>Mondadori</editore>
<parola_chiave>romanzo</parola_chiave>
<parola_chiave>storico</parola_chiave>
</libro>
<prestito codicelibro="A438" >
<utente>
<cognome>Damon</cognome>
<nome>Crudelia</nome>
</utente>
</prestito>
<prestito codicelibro="Z096" >
<utente>
<cognome>Ghini</cognome>
<nome>Vittorio</nome>
</utente>
</prestito>
</biblioteca>
Ricerche in documenti XML - XPath
XPath
Gli XPath sono una sintassi comune per esprimere locazioni all’interno di
documenti XML.
XPath opera sulla struttura logica del documento, non su quella sintattica,
usando una sintassi non XML accettabile all’interno di URI e attributi.
Un XPath è un espressione che restituisce un oggetto di uno di questi quattro
tipi:
• Un booleano
• Una stringa
• Un numero
• Un insieme di nodi (nodi elemento, nodi attributi, nodi testo)
Introduzione Informale ai Location Path
Il tipo più importante di XPath è il Location Path. Questo può essere o assoluto
o relativo. Un Location Path assoluto inizia con ‘/’.
Un Location Path è composto di una sequenza di passi di locazione (Location
Steps) separati da ‘/’, e letti da sinistra a destra. Ogni termine individua più
precisamente un frammento della risorsa individuata in precedenza.
Esempi notevoli: percorsi assoluti che partono dalla radice
Es.:
/child::biblioteca/child::libro/child::autore/child::nome
identifica gli elementi “nome” che siano figli diretti di un elemento “autore”
che sia figlio diretto di un nodo “libro“ che sia figlio diretto della radice
“biblioteca” del documento XML.
Es.: /child::biblioteca/descendant::nome
Es.: /child::biblioteca///::nome
identifica gli elementi “nome” che discendano anche non direttamente dalla
radice “biblioteca” del documento XML. Attenzione, che questo vuol dire che io
otterro’ sia nome come figlio di autore, sia nome come figlio di utente.
Es.:
Es.:
/child::biblioteca/child::libro[position()=3]/child::autore/child::nome
/child::biblioteca/child::libro[3]/child::autore/child::nome
identifica gli elementi “nome” che siano figli diretti di un elemento “autore”
che sia figlio diretto di un nodo “libro“ che sia il terzo figlio diretto della
radice “biblioteca” del documento XML.
Es.:
/child::biblioteca/child::libro[last()]/child::autore/child::nome
identifica gli elementi “nome” che siano figli diretti di un elemento “autore”
che sia figlio diretto di un nodo “libro“ che sia l’ultimo figlio diretto della
radice “biblioteca” del documento XML.
Es.:
Es.:
/child::biblioteca/child::libro[Attribute::tipocarta=’lucida’]/child::autore/child::nome
/child::biblioteca/child::libro[@tipocarta=’lucida’]/child::autore/child::nome
identifica gli elementi “nome” che siano figli diretti di un elemento “autore”
che sia figlio diretto di un nodo “libro“ che abbia come attributo tipocarta il
valore “lucida“ e che sia figlio diretto della radice “biblioteca” del documento
XML.
Es.:
/child::biblioteca/descendant::autore[cognome != ‘Asimov’]
identifica tutti gli elementi “autore”, discendenti della radice “biblioteca”
del documento XML, che abbiano cognome diverso da ‘Asimov‘.
Es.:
/child::biblioteca/descendant::autore[cognome = ‘Asimov’]/parent::libro/child::editore
identifica tutti l’elemento editore del libro di Asimov. Prima trova l’elemento
Asimov, poi sale di un livello e trova il libro, poi scende di livello cercando
l’autore.
Es.:
/child::biblioteca/child::libro[last()]/child::autore/child::nome
identifica gli elementi “nome” che siano figli diretti di un elemento “autore”
che sia figlio diretto di un nodo “libro“ che sia l’ultimo figlio diretto della
radice “biblioteca” del documento XML.
Esempi notevoli: ricerca di valori testuali (non di elementi)
/child::biblioteca/descendant::autore[cognome=’Asimov’]/parent::libro/child::editore/child::text()
Restituisce la stringa di testo (non un elemento) che e’ il valore testuale
dell’elemento editore del libro di Asimov. Il valore dell’elemento viene pensato
come un figlio testuale ( usare funzione text() ) dell’elemento stesso.
/child::biblioteca/descendant::autore[cognome=’Asimov’]/parent::libro/attribute::tipocarta
Restituisce la stringa di testo (non un elemento) che e’ il valore testuale
dell’attributo tipocarta del libro di Asimov. Il valore dell’attributo e’ un
dato testuale.
Esempi notevoli: percorsi assoluti che partono da un nodo identificato dal suo
identificatore univoco
Es.:
id( ‘Z096’ )
notare gli apici semplici
identifica e restituisce, se esiste, quell’unico elemento che abbia un attributo
univoco (cioè quello di tipo ID) che abbia il valore indicato tra le parentesi.
Nel nostro esempio restituisce l’elemento di tipo libro che ha come attributo
codice il valore (la stringa testuale) ‘A438’, cioe’ il libro di Asimov IO Robot.
Es.:
id( ‘Z096’ )/child::autore/child::nome
identifica e restituisce, se esiste, il nome dell’autore dell’unico elemento che
abbia come attributo univoco il valore indicato tra le parentesi. Nel nostro
esempio restituisce l’elemento di tipo nome “Isaac“.
Es.:
id( ‘Z096’ )/parent::*
identifica e restituisce, l’elemento padre del nodo che ha come attributo
univoco il valore indicato tra le parentesi. Nel nostro esempio poiché
l’elemento con quel codice e’ un libro, il padre dell’elemento sara’ biblioteca,
e l’espressione restituisce tutto l’elemento biblioteca.
Es.:
id( ‘Z096’ )/attribute::tipocarta
identifica e restituisce la stringa di testo che e’ il tipo di carta del libro
di Aimov
Esempi notevoli: composizione di condizioni su nodi: operatori logici OR e NAD
Es: /child::biblioteca/descendant::autore[cognome=’Asimov’ or nome=’Alessandro’]/parent::libro
Restituisce gli elementi libro scritti o da Isaac Asimov o da Alessandro Manzoni.
Es.: /child::biblioteca/descendant::autore[cognome=’Asimov’ and nome=’Isaac’]/parent::libro
Restituisce gli elementi libro scritti da un autore che deve avere cognome
Asimov e nome Isaac.
/child::biblioteca/descendant::autore[cognome=’Asimov’ or
( nome=’Alessandro’ and cognome=’Manzoni’) ]/parent::libro
Restituisce gli elementi libro scritti o un autore che ha cognome Asimov oppure
da un autore che deve avere nome Alessandro e cognome Manzoni.
Esempi notevoli: uso di funzioni su stringhe
Es.: analoghi
/child::biblioteca/child::prestito/child::utente/child::cognome[contains(child::text(),'ini')]
/child::biblioteca/child::prestito/child::utente[contains(child::cognome/child::text(),'ini')]
/child::biblioteca/child::prestito/child::utente[contains(child::cognome,'ini')]
Esempi notevoli: annidamento delle Location Path
Premessa:
/child::biblioteca/child::prestito/child::utente[nome='Crudelia']/parent::presti
to/attribute::codicelibro
con questo trovo il valore testuale del codice del libro prestato a Crudelia, e
poi, qui sotto, lo userò per trovare il libro prestato a Crudelia e quindi il
titolo
id(
/child::biblioteca/child::prestito/child::utente[nome='Crudelia']/parent::pre
stito/attribute::codicelibro
)/child::titolo/child::text()
ottiene il titolo del libro prestato a Crudelia. Notate che ho utilizzato l’
Xpath precedente e l’ho inserita come argomento della funzione id(). Notate
anche che ho inserito come argomento della funzione id NON l’elemento titolo
bensì la stringa di testo che e’ il valore dell’elemento titolo.
In modo analogo, qui sotto, notare il modo differente in cui inserisco la
condizione sul nodo utente, in modo da non dover scendere e poi dover risalire
con parent.
id( /child::biblioteca/child::prestito[
child::utente/child::nome='Crudelia'
]
/attribute::codicelibro
)/child::titolo/child::text()
Esempi notevoli: unione dei risultati delle ricerche
Es.:
id( ‘Z096’ ) | id( ‘A438’ )
notare gli apici semplici
Restituisce un insieme di due elementi, ciascuno dei quali ha come
identificatore univoco uno dei due valori tra le parentesi. Quindi restituisce i
due elementi libro di Asimov e libro di Manzoni.
Esempi notevoli: selezione di un dato sottolivello
Es.:
/child::biblioteca/child::*/ child::*/child::text
Restituisce l’insieme dei valori testuali degli elementi semplici che siano
nipoti di biblioteca (cioe’ figli dei figli di biblioteca e che abbiano come
figlio un dato testuale). In definitiva, restituisce l’insieme delle stringhe di
testo contenute negli elementi titolo, editore, parola_chiave
Esempi notevoli: interrogazione annidata, con CONFRONTO tra ELEMENTI COMPOSITI
L’insieme di tutti i libri degli autori di cui io (Ghini) ho libri in prestito.
Questa ricerca viene svolta in cinque passi successivi:
1) Prima cerco il codice univoco dei libri che io (ghini) ho in prestito,
2) poi cerco questi libri,
3) poi cerco gli autori di questi libri,
4) ed infine cerco tutti i libri di questi autori.
/child::biblioteca/child::libro[
child::autore
=
id(
/child::biblioteca/child::prestito[
child::utente/child::cognome='Ghini'
]/attribute::codicelibro
)/child::autore
]
notare che faccio un confronto non tra elementi semplici, ma tra elementi
compositi (nel caso specifico, confronto gli autori, che sono formati da diverse
parti)
Sintassi generale delle XPath
Alla luce degli esempi precedenti possiamo così sintetizzare:
un XPath è un espressione che restituisce un oggetto di uno di questi quattro
tipi:
• Un booleano
• Una stringa
• Un numero
• Un insieme di nodi (nodi elemento, nodi attributi, nodi testo)
Il tipo più importante di XPath è il Location Path. Un Location Path è composto
di una sequenza di passi di locazione (Location Steps) separati da ‘/’, e letti
da sinistra a destra. Ogni termine individua più precisamente un frammento della
risorsa individuata in precedenza.
step
step
step
step
/child::biblioteca/descendant::autore[cognome=‘Asimov’]/parent::libro/child::editore
•
Si parte da una data posizione (il cosiddetto Nodo Contesto) che può
essere:
- Assoluta
/
id( valoreidentificatoreunivoco )
la radice del documento
il nodo con quell’identificatore
- Relativa
Il nodo a cui sono arrivato con il precedente step
•
Ad ogni passo (step)
•
•
•
•
Indico la direzione in cui cerco i nuovi nodi (si chiama asse, axis )
Considero i nodi che incontro nella direzione scelta.
Seleziono questi nodi e tengo solo quelli che superano le condizioni
che impongo (test di nodo)
I nodi selezionati diventano la posizione di partenza del nuovo step,
in cui applichero’ una nuova direzione e nuove condizioni.
Direzioni (assi, AxisName)
'ancestor'
'ancestor-or-self'
'attribute'
'child'
'descendant'
'descendant-or-self'
'following'
'following-sibling'
'namespace'
'parent'
'preceding'
'preceding-sibling'
'self'
tutti i nodi antenati
gli attributi
i nodi figli diretti
i nodi discendenti (figli, nipoti, ..)
il nodo padre
il nodo stesso
Test di Nodo, ovvero test sull’insieme dei nodi collezionati ad un dato step
sul valore di un elemento testuale
sul valore di un attributo
Funzioni sugli insieme di nodi, ovvero funzioni predefinite con cui posso effettuare operazioni di
test.
number
last()
number
position()
number
count( insieme_di_nodi)
nodo
id( identificatore_univoco)
Funzioni sulle stringhe
string string(object?)
string concat(string, string, string*)
boolean starts-with(string, string)
boolean contains(string, string)
string substring-before(string, string)
string substring-after(string, string)
string substring(string, number, number?)
number string-length(string?)
string normalize-space(string?)
string translate(string, string, string)
Funzioni sui numeri
number number(object?)
number sum(node-set)
number floor(number)
number ceiling(number)
number round(number)
Riferimenti Bibliografici
[1] "Extensible Markup Language (XML) 1.0 Specification", available
http://www.w3.org/TR/1998/REC-xml-19980210.html
[2] "XML Path Language (XPath) Version 1.0, available
http://www.w3.org/TR/1999/REC-xpath-19991116
[3] "XML Schema Home Page", http://www.w3.org/XML/Schema
[4] "Extensible Stylesheet Language (XSL) Version 1.1",
http://www.w3.org/TR/xsl/
[5] "XQuery 1.0: An XML Query Language", http://www.w3.org/TR/xquery/
Scarica

I Dati