Individuare gli elementi di un documento XML rappresenta il primo passo di un'elaborazione per la presentazione dei dati. Nei CSS questo ruolo è svolto dal selettore, cioè l'elemento sintattico di una regola CSS che individua gli elementi da formattare.
In XSL questo passo viene descritto tramite il linguaggio XPath. A differenza dei selettori CSS, però, XPath è molto più potente e flessibile.
Questo linguaggio consente di creare espressioni dichiarative, chiamate espressioni XPath o pattern, che individuano i vari nodi dell'albero di rappresentazione di un documento XML.
La sua sintassi è molto compatta e, per certi versi, ricorda un po' le espressioni per individuare il percorso di un file o una cartella su un file system.
Il simbolo '/' rappresenta il root element di un documento XML. facendo riferimento al seguente documento XML, l'espressione '/' rappresenta l'elemento articolo:
<?xml version="1.0" ?>
<articolo titolo="">
<paragrafo titolo="Titolo del primo paragrafo">
<testo>
Blocco di testo del primo paragrafo
</testo>
<immagine file="immagine1.jpg">
</immagine>
</paragrafo>
<paragrafo titolo="Titolo del secondo paragrafo">
<testo>
Blocco di testo del secondo paragrafo
</testo>
<codice>
Esempio di codice
</codice>
<testo>
Altro blocco di testo
</testo>
</paragrafo>
</articolo>
Per individuare l'elemento <testo> all'interno del nostro esempio di documento XML dobbiamo specificare un percorso di questo tipo:
/articolo/paragrafo/testo
Se siamo interessati all'attributo titolo dell'elemento <paragrafo> possiamo specificarlo nel modo seguente:
/articolo/paragrafo/@titolo
Queste espressioni, però, individuano il primo elemento che corrisponde al percorso. Per selezionare uno specifico elemento, ad esempio il paragrafo con titolo Titolo del secondo paragrafo, possiamo farlo con l'espressione seguente:
/articolo/paragrafo/[@titolo=ìTitolo del secondo paragrafoì]
In pratica, all'interno delle parentesi quadre specifichiamo la condizione che deve essere soddisfatta dall'elemento.
Per selezionare un elemento specifico è possibile utilizzare anche alcune funzioni predefinite, come position(), che specifica la posizione di un elemento, e last(), che specifica l'ultima posizione di una sequenza di elementi. Ad esempio, le due espressioni seguenti specificano rispettivamente il secondo paragrafo e l'ultimo paragrafo dell'articolo:
/articolo/paragrafo[position()=2]
/articolo/paragrafo[position()=last()]
Gli esempi di pattern che abbiamo visto rappresentano percorsi assoluti, cioè individuano un elemento partendo dall'elemento root. Un importante concetto è quello di nodo corrente, cioè il nodo che si è appena individuato. Il concetto è analogo a quello di cartella corrente per i file system.
Il nodo corrente viene indicato con il punto '.', mentre il nodo genitore del nodo corrente viene indicato con i due punti '..' . La doppia barra '//' consente di individuare tutti i discendenti di un particolare elemento. Ad esempio, l'espressione
/articolo/paragrafo//immagine
individua tutti gli elementi <immagine> contenuti nell'elemento <paragrafo>, a qualsiasi livello.
Per individuare tutti i sottoelementi di un certo elemento possiamo utilizzare l'asterisco (*). Ad esempio, per selezionare tutti gli elementi del secondo paragrafo possiamo scrivere la seguente espressione XPath:
/articolo/paragrafo[position()=2]/
Esistono numerose altre possibilità per costruire espressioni di ricerca, soprattutto sfruttando le varie funzioni predefinite che XPath mette a disposizione.
Abbiamo visto negli esempi precedenti le funzioni position() e last() che restituiscono rispettivamente la posizione dell'elemento corrente e la posizione dell'ultimo elemento. Un'altra funzione che lavora sugli elementi è count(), che restituisce il numero di elementi relativi all'espressione passata come argomento.
Ad esempio, count(//paragrafo) restituisce il numero di elementi paragrafo nel documento corrente.
Altre funzioni risultano molto utili in situazioni diverse. Ad esempio, sono previste funzioni di manipolazione di stringhe, come concat() che concatena le stringhe passate come parametro. Per esempio, concat("par", "agra", "fo") restituisce la stringa "paragrafo".
La funzione substring() restituisce una sottostringa in base ai parametri specificati. Ad esempio, substring("paragrafo", 5, 3) restituisce la sottostringa "gra", poiché estrae tre caratteri iniziando dal quinto carattere della stringa "paragrafo".
La funzione string-length() restituisce il numero di caratteri che compongono la stringa specificata come parametro.
Un'altra utile funzione è starts-with() che restituisce true se il primo parametro di tipo stringa inizia con la stringa passata come secondo parametro. Ad esempio, starts-with("paragrafo", "par") restituisce true. Analogamente esiste la funzione ends-with() che valuta la parte finale di una stringa.
Altre funzioni consentono di manipolare espressioni numeriche. Ad esempio, la funzione number() converte il valore passato come parametro in un numero, mentre round() arrotonda un numero all'intero più vicino, floor() restituisce l'intero uguale o precedente al parametro passato e ceiling() restituisce l'intero uguale o successivo.
Queste ed altre funzioni definite dalle specifiche di XPath contribuiscono ad ottenere espressioni molto potenti.