Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

XPath: costruire le espressioni

La struttura delle espressioni e le funzioni principali del più importante linguaggio di interrogazione per XML
La struttura delle espressioni e le funzioni principali del più importante linguaggio di interrogazione per XML
Link copiato negli appunti

Lo sviluppo di tecnologie diverse ha portato la necessità di creare una notazione flessibile per navigare all'interno di un documento XML. Il risultato finale è XPath, utilizzato da XML per determinare l'identità e descrivere i campi d'azione.

Abbiamo già parlato di XPath nella Guida linguaggi XML. In questo articolo riprenderemo alcuni dei concetti già visti ma approfondiremo maggiormente alcuni costrutti fondamentali di XPath. In particolare ci concentreremo sulla costruzione delle espressioni i cosiddetti "Location Path" e le parti che li compongono, i "Location Step"

Esempio di espressione XPath

rcp:esempio[@qunant='4' and @unita='tazza']/@home

Location Step

In XPath un percorso (Location Path) definisce una sequenza di nodi in un albero XML. La sequenza risultante rispetterà sempre l'ordine del documento e non conterrà mai duplicati di nodi identici. La sequenza dei nodi è definita come una sequenza di "Location Step" (passi di locazione) separati da un carattere "slash" (/), ognuno dei quali è composto da:

  • asse
  • test di nodo
  • e da 0 a N predicati

Ricapitolando avremo la seguente situazione:

asse :: testnodo [espr1]...[esprN]

L'espressione viene valutata a partire da un nodo principale poi si scende nelle diramazioni seguendo i passi di locazione. Questo nodo principale viene anche chiamato "contesto" perché determina il punto iniziale della ricerca.

La valutazione di un'espressione produce una serie di N nodi. Generalizzando possiamo dire che una trasformazione prende una sequenza di nodi in input e ne restituisce un'altra.

A questo punto è facile definire il comportamento di un percorso di locazione (path) come il risultato dei comportamenti dei passi (step) che lo compongono. Per capire meglio, cominciamo osservando lo schema:

Figura 1. Albero XML di esempio
Esempio di Albero XML

Ogni nodo dell'albero ha un indice numerico univoco che lo contraddistingue ed una lettera come descrizione. Prendiamo, come esempio, il seguente percorso:

descendant :: C/child :: F
  1. Si parte sempre dalla radice dell'albero che nel nostro caso è A1
  2. Prendiamo il primo pezzo del percorso: descendant :: C; quindi partendo dalla radice prendiamo tutti i nodi con descrizione C e che siano discendenti del nodo radice (A1)
  3. Otteniamo la seguente serie di nodi: C4, C5, C9.
  4. Il passo successivo è valutare i figli di C.
  5. Infatti prendendo la seconda parte del percorso, child :: F bisogna valutare i figli che siano etichettati come F.
  6. Quindi avremo come risultato finale la seguente serie di nodi: F8, F11, F12.

I Contesti

Il contesto di un'espressione XPath è caratterizzato da:

  • un nodo contesto (nodo appartenente all'albero XML)
  • posizione e dimensioni del contesto (due numeri)
  • un insieme di legami di variabili
  • una libreria di funzioni
  • un insieme di dichiarazioni di namespace

Il contesto iniziale è determinato dall'applicazione che invoca la valutazione dell'XPath. Durante la valutazione di uno o piu passi di locazione abbiamo visto che il nodo contesto varia e così anche la sua posizione e le sue dimensioni (numero di nodi coinvolti).

Se nel passo i-esimo abbiamo ottenuto una lunghezza pari a N; il passo successivo i+1, il contesto sarà il nodo stesso. Più avanti, nel corso dell'articolo vedremo che la posizione e la lunghezza del contesto servono per la valutazione dei predicati.

Gli Assi

L'asse determina la relazione che intercorre tra il nodo di contesto e gli altri nodi nell'albero. Determinare un asse in un Location Step significa voler selezionare i nodi che hanno una precisa relazione con il contesto.

XPath prevede 12 tipologie di relazione:

Relazione Abbreviazione Descrizione
child niente asse rappresenta i figli del nodo contesto
descendant sono i discendenti del nodo contesto
parent .. padre del nodo contesto
ancestor antenati del nodo contesto
following sono tutti i fratelli
following-sibling sono i fratelli posti "a destra" (nella rappresentazione) rispetto il nodo contesto
preceding-sibling sono i fratelli posti "a sinistra" rispetto il nodo contesto
self . il nodo contesto
descendant-or-self // concatenazione di self + descendant
ancestor-or-self concatenazione di self + ancestor
attribute @ tutti i nodi attributi

Possiamo anche non definire l'asse in un Location Step. In questo caso viene considerata la relazione child per default. Altre relazioni consentono forme abbreviate, come parent, che si può sostituire con due punti (..).

Ecco qualche altro esempio di utilizzo delle relazioni.

Tipi di nodo (testnodo)

Il primo test che rifinisce la ricerca è quello che ci permette di indicare che tipo di nodo stiamo cercando. I tipi di nodo sono:

  • elementi particolari: quelli designati da nome e namespace (es. <asp:TextBox>//asp.TextBox tutti i nodi TextBox del namespace asp)
  • text: i nodi testo, ovvero il testo presente all'interno degli elementi o al di fuori (es. blabla è il nodo testo nella stringa <div>blabla</div>)
  • comment: sono i nodi commento
  • node: tutti i nodi presente nell'albero XML
  • processing-instruction: i nodi che contengono istruzioni (es. <?php echo "andimar" ?>)

Predicati

I predicati sono espressioni che ci aiutano a rifinire ulteriormente le ricerche. Queste espressioni possono essere soddisfatte dal nodo, se le caratteristiche del nodo rendono l'espressione verificata, oppure no. Ne primo caso il nodo appartiene all'insieme dei nodi ricercati, nel secondo il nodo viene scartato.

I predicati sono racchiusi tra parentesi quadre e possono essere aggiunti in coda a qualunque Location Step.

È possibile combinare N espressioni attraverso gli operatori logici and, or e not. Un esempio di espressione è la seguente:

descendant :: C/child :: F[attribute::nome='esempio']

In questo caso selezionerà tutti i nodi F, figli del nodo C e con l'attributo nome uguale a "esempio".

I valori prodotti possono appartenere anche a tipi diversi dal boolean come numeri, caratteri, stringhe e sequenze e sono convertiti automaticamente in booleani come segue:

  • un numero vale true quando il suo valore è identico alla posizione corrente del contesto
  • una stringa vale true quando la sua lunghezza è maggiore di zero
  • una sequenza vale true quando la sua lunghezza è maggiore di zero

Commenti in XPath

Come tutti i linguaggi anche XPath dispone di una notazione particolare per inserire dei commenti. I commenti hanno la seguente sintassi:

(: commento :)

Le Espressioni

Abbiamo già osservato l'importanza delle espressioni in XPath. Ne esistono diverse tipologie, osserviamone alcune.

Espressioni Booleane

XPath supporta gli operatori logici and, or e not. la loro combianzione forma un'espressione booleana che restituisce come risultato true o false. L'espressione restituisce true per le seguenti condizioni:

  • il valore booleano true
  • una stringa non vuota
  • una sequenza di lunghezza maggiore di 0

Sequenze

Possiamo definire la sequenza di espressioni come una concatenazione di N espressioni con N > 0. Se N = 0 la sequenza si dice vuota.

Espressione1, Espressione2,...,EspressioneN

L'espressione Espressione1 to Espressione4, restituisce una sequenza di valori che dall'espressione 1 arrivi fino all'espressione 4. Un esempio è il seguente:

1 to 5 restituirà la sequenza: 1, 2, 3, 4, 5

Le sequenze che contengono esclusivamente nodi possono essere combinate con gli operatori union, intersect ed exept

Filtri

I predicati dei percorsi di locazione possono essere generalizzati in sequenze arbitrarie che contengono un insieme di nodi e valori. La sintassi è la seguente:

Espressione1[Espressione2]

che permette di usare come filtri espressioni arbitrarie forzate a una valutazione booleana.

Espressioni aritmetiche ed espressioni letterali

XPath supporta tutti gli operatori aritmetici. Possiamo effettuare le operazioni fondamentali (+,-,*,/) su tutti i tipi numerici (interi, decimali, float e double), inoltre li interi supportano la divisione intera (idiv) e l'operatore di modulo (mod).

Un'espressione letterale denota un valore atomico costante o più precisamente una sequenza singleton, ovvero che contiene un solo valore.

Espressioni di Confronto

Le espressioni di confronto in XPath si suddividono in tre categoria; confronti tra valori, confronti generali e confronti tra nodi.

Confronto tra nodi

Il confronto tra i nodi viene effettuato attraverso i seguenti operatori

Operatore Descrizione
is operatore di identità, stabilisce se due espressioni rappresentano lo stesso nodo (es. nota[1] is *[@nome="la"][1] è verificata se il primo figlio di nota è anche il primo nodo che ha attributo nome="la"
isnot il cotrario di is
<< verifica che il primo nodo sia precedente al secondo
>> verifica che il primo nodo sia successivo al secondo

Esempio di confronto tra nodi

/rcp::C << (rcp::F)

Confronto generale

Il confronto generale utilizza i seguenti operatori:

Operatore Descrizione
= Uguale
!= Diverso
< Minore
> Maggiore
<= Minore o Uguale
>= Maggiore o Uguale

e vengono utilizzati per confrontare tutti i valori. Un esempio può essere il seguente:

descendant :: C/child :: F = 3

Confronto tra valori

Il confronto tra valori, invece, utilizza i seguenti operatori:

Operatori
eq ne lt gt le ge

e vengono utilizzati per confrontare i singoli valori atomici. Un esempio può essere il seguente:

//rcp:descrizione/text() eq "Esempio di confronto per valore"

Funzioni

XPath mette a disposizione una serie di operatori e funzioni che si rivelano alla elaborazione dei dati. Cerchiamo di esaminare i blocchi di funzioni più importanti.

Funzioni Booleane

Funzione Descrizione
fn:true() restituisce il valore booleano true
fn:false() restituisce il valore booleano false
fn:not(expr) effettua l'operazione logica di negazione (not) alla espressione inserita

Esempi

fn:true()  = true
fn:false() = false
fn:not(1)  = false
fn:not(0)  = true

Funzioni di Stringa

Funzione Descrizione
fn:concat(stringa1, ..., stringaN) concatena le stringhe inserite nella funzione
fn:string-join((stringa1, ..., stringaN), stringaReplace) è la combinazione di una concatenazione e di un Replace
fn:substring(stringa, partenza, fine) restituisce la sottostringa
fn:string-length(stringa) restituisce il numero di caratteri che compongono la stringa
fn:lower-case(stringa) restituisce la stringa con caratteri minuscoli
fn:upper-case(stringa) restituisce la stringa con caratteri maiuscoli

Esempi

fn:concat("esempio", " di ", " prova")    = "esempio di prova"
fn:string-join(("1", "2", "3", "4"), "+") = "1+2+3+4"
fn:substring("esempio di prova", 2, 5)    = "sempi"
fn:string-length("esempio di prova")      = 16
fn:lower-case("STRINGA")                  = "stringa"
fn:upper-case("stringa")                  = "STRINGA"

Funzioni Matematiche

Funzione Descrizione
fn:max(numero1, ..., numeroN) restituisce il numero massimo della serie
fn:min(numero1, ..., numeroN) restituisce il numero minimo della serie
fn:sum(numero1, ..., numeroN) restituisce la somma della serie
xs:integer(numero) restituisce l'intero
xs:decimal(numero) restituisce il numero con i decimali
xs:float(numero) restituisce il numero in formato float (virgola mobile)
xs:double(numero) restituisce il numero in formato double (virgola mobile, doppia precisione)

Esempi

fn:max(1, 2, 3, 4, 5, 6, 7, 8)  : 8
fn:min(1, 2, 3, 4, 5, 6, 7, 8)  : 1
fn:sum(1, 2, 3, 4, 5)           : 15
xs:integer(3.5)                 : 3
xs:decimal(3)                   : 3.0
xs:float(2)                     : 2.0E0
xs:double(14.3)                 : 1.43E1

Ti consigliamo anche