XPath
Da Wikipedia, l'enciclopedia libera.
XPath è una sintassi che permette di individuare nodi di un documento XML, analogamente alle directory e i file in un file system.
XPath è originalmente nato dall'esigenza di fornire una sintassi e un comportamento comune fra XPointer e XSL, è stato velocamente adottato dagli sviluppatori come metodo di interrogazione di dati in formato XML.
Indice |
[modifica] Notazione
Il tipo più comune di espressione XPath (e quella che ha dato origine al suo nome) è la path expression. Una path expression è scritta come una sequenza di steps per ottenere un nodo XML, partendo dal nodo corrente (percorso relativo). In alternativa è possibile utilizzare dei percorsi "assoluti" utilizzando come riferimento la radice del documento. Gli elementi sono separati dal carattere '/'. Ogni elemento ha tre componenti:
- Axis Specifier
- Node test
- Predicato
Sono state definite due notazioni, la sintassi abbreviata, più compatta che permette la realizzazione di costrutti intuitivi e facilmente realizzabili. La sintassi completa, più complessa, che contiene più opzioni, in grado di specificare con più particolarità gli elementi.
[modifica] Sintassi abbreviata
La notazione abbreviata permette molte diffrenti sintassi per i casi comuni. L'XPath più semplice ha una forma del tipo:
/A/B/C
che seleziona gli elementi di C che sono figli degli elementi B che sono figli dell'elemento A che rappresenta la radice del documento XML. La sintassi XPath è stata progettata per imitare la sintassi del URI (Uniform Resource Identifier) e quella usata per indicare i file o le directoy nei file system.
Le espressioni più complesse possono essere costruite specificando un Axis differente da un semplice nome o predicato, che può essere scritto fra parentesi quadre dopo tutta l'espessione. Per esempio:
A//B/*[1]
seleziona il primo elemento ("[1]"), figlio di B, indipendentemente dal suo nome, e dal numero di nodi che intercorrono tra A e B (//). Da notare che l'esperssione non inizia con "/", quindi A è un nodo del contesto corrente.
[modifica] Sintassi espansa
Nella sintassi completa, i due esempi qui sopra sarebbero scritti:
/child::A/child::B/child::C
child::A/descendant-or-self::B/child::node()[1]
In questo caso, ad ogni punto del XPath, l'Axis (per esempio child o descendant-or-self) è specificato esplicitamente, seguito da :: ed ancora seguito dal test del nodo, come A o node() degli esempi sopra citati.
[modifica] Axis
L'Axis indica il senso di percorrenza dell'albero del documento XML. Gli Axis disponibili, nella sintassi completa ed abbreviata, sono:
- child
- default, non specificato nella sintassi abbreviata
- attribute
- @
- descendant
- non disponibile nella sintassi abbreviata
- descendant-or-self
//
- parent
..
- ancestor
- non disponibile nella sintassi abbreviata
- ancestor-or-self
- non disponibile nella sintassi abbreviata
- following
- non disponibile nella sintassi abbreviata
- preceding
- non disponibile nella sintassi abbreviata
- following-sibling
- non disponibile nella sintassi abbreviata
- preceding-sibling
- non disponibile nella sintassi abbreviata
- self
.
- namespace
- non disponibile nella sintassi abbreviata
Ad esempio, usando la seguente sintassi abbreviata, //a/@href
si seleziona un attributo denominato href
in un qualunque elemento dell'albero del documento. L'Axis self
è più comunemente usato per riferirsi al nodo attualmente selezionato. Per esempio, h3[.='See also']
seleziona un elemento denominato h3
nel contesto corrente, il cui testo è uguale a "See also".
[modifica] Test Node
I test node possono controllare nomi specifici di nodi o espressioni più generali. Nel caso di un documento XML in cui il prefisso del namespace gs
è stato definito, //gs:enquiry
troverà tutti i nodi enquiry
di quel namespace.
Altri node test sono:
- comment()
- trova un nodo di commento XML, per esempio
<!-- Commento -->
- text()
- trova un nodo di tipo testo, per esempio
hello
in<k>hello</k>
- processing-instruction()
- trova istruzioni di processamento XML come
<?php echo $a;?>
. In questo caso ('php'). - node()
- trova il nodo.
[modifica] Predicati
Espressioni di qualunque entità possono essere indicate fra parentesi quadre, le quali dovranno essere soddisfatte affinché il nodo possa essere preso in considerazione. Ad esempio //a[@href='help.php']
, che abbinerà un elemento con un attributo href
di cui il valore è help.php
. Non c'è limite al numero di predicati e non devono essere limitati all'ultimo elemento di un'espressione XPath. Possono anche essere annidati. I percorsi specificati nei predicati faranno riferimento al contesto del relativo punto (cioè quello immediatamente prima del test del nodo).
//a[@href='help.php'][../div/@class='header']/@target
selezionerà il valore dell'attributo target di un elemento a
, se l'elemento ha un attributo href
il cui valore è help.php
e se il parent è un elemento div
che ha un attributo class
di valore header
[modifica] Funzioni ed operatori
XPath 1.0 definisce quattro tipi di dati: node-set (insiemi di nodi senza ordine intrinseco), stringhe, numeri e booleani.
Gli operatori disponibili sono:
- Operatori "/", "//" e [...] usati nelle espressioni del percorso, come precedentemente descritto.
- Un operatore di unione, "|", che forma l'unione di due node-set.
- Operatori booleani "and" e "or" e la funzione "not()".
- Operatori aritmetici "+", "-", "*", "div" e "mod".
- Operatori di confronto "=", "!=", "<", ">", "<=", ">=".
La function library include:
- Funzioni per manipolare stringhe: concat(), substring(), contains(), substring-before(), substring-after(), translate(), normalize-space(), string-length()
- Funzioni per manipolare numeri: sum(), round(), floor(), ceiling()
- Funzioni per accedere alle proprietà dei nodi: name(), local-name(), namespace-uri()
- Funzioni per accedere a informazioni del contesto del nodo: position(), last()
- Funzioni per la conversione dei tipi: string(), number(), boolean()
Alcune delle funzioni più conunementi sono dettagliate successivamente. Per una descrizione completa, si veda il documento di riferimento del W3C
[modifica] Funzioni su i nodi
- position()
- restituisce un numero che rappresenta la posizione di questo nodo rispetto ai relativi fratelli dal XPath a questo punto.
- count(node-set)
- restituisce il numero di nodi che corrispondono alla relativa richiesta
[modifica] Funzioni per la manipolazione di stringhe
- string(object?)
- converte ognuno dei quattro tipi di dati di XPath in una stringa. L'argomento può essere un XPath, nel qual caso i nodi abbinati sono convertiti in stringa.
- concat(string, string, string*)
- concatena tutte le stringhe.
- contains(s1, s2)
- restituisce true se s1 contiene s2.
- normalize-space(string?)
- tutti i whitespace all'inizio e alla fine vengono rimossi e tutte le sequenze di whitespace sono sostituite da un singolo spazio. È molto utile quando l'XML originale dev'essere ben formattato, in grado di rendere ulteriormente fidata elaborazione della stringa.
[modifica] Funzioni booleane
- not(boolean)
- nega tutta l'espressione booleana.
[modifica] Funzioni numeriche
- sum(node-set)
- Converte i valori della stringa di tutti i nodi trovati, in numeri, quindi estituisce la somma di questi numeri.
Le espressioni possono essere generate usando gli operatori: =, !=, <=, <, >=
e >
. Le espressioni booleane possono essere unite con le parentesi ()
e combinate con operatori booleani and
, or
and not()
. I calcoli numerici possono usare *, +, -, div
and mod
. Le stringhe possono consistere di tutti i caratteri di Unicode.
All'interno o all'esterno dei predicatui, interi node-set possono essere unuti usando il carattere | ("pipe").
v[x or y] | w[z]
restituirà un singolo node-set con tutti gli elementi di v
che hanno come figli elementi y
o x
, insieme a tutti gli elementi di w
che hanno figli z
, trovati nel contesto corrente.
//item[@price > 2*@discount]
seleziona gli item
di cui l'attributo price
è maggiore del doppio del valore dell'attributo discount
.
[modifica] Esempi pratici
Analizziamo ora un semplice documento XML per capire meglio come accedere ai dati in esso contenuti.
<?xml version="1.0"?> <listautenti> <account user="fabio"> <mail>fabio@aaaa.com</mail> <nome>Fabio V.</nome> <principale> <indirizzo> <via>Via Vai 1</via> <cap>98100</cap> <citta>Messina</citta> </indirizzo> <telefoni> <fisso>090123456</fisso> <cellulare gestore="aaa">3001234567</cellulare> </telefoni> </principale> <altrirecapiti> <ufficio> <indirizzo> <via>Via di Qua, 2</via> <cap>98100</cap> <citta>Messina</citta> </indirizzo> <telefoni> <fisso>09078901</fisso> <fax>3001234567</fax> </telefoni> </ufficio> </altrirecapiti> </account> </listautenti>
/listautenti/account/telefoni/*
:restituisce la lista di tutti i nodi all'interno del nodotelefoni
, in questo casofisso
ecellulare
./listautenti/account//indirizzo/..
- restituisce tutti i nodi che contengono un nodo
indirizzo
al loro interno, l'impiego dell'Axis//
fa sì che vengano individuati anche nodi di livelli differenti purché all'interno diaccount
.