Le langage de requête XPATH

Introduction

Présentation

♦ Le langage XPATH offre un moyen d'identifier un ensemble de noeuds dans un document XML.

♦ Toutes les applications ayant besoin de repérer un fragment de document XML peuvent utiliser ce langage.

♦ Les feuilles de style XSL, les pointers XPOINTER et les liens XLINK utilisent de manière intensive les expressions XPATH.

♦ XPATH est un premier pas vers un langage d'interrogation d'une base de données XML (XQuery).

Structure d'arbre d'un document XML

img-xpath/xpath-arbre.png
<!-- Texte -->
<stock>
  <produit>
    <nom> Livre </nom><prix monnaie="Francs"> 50 </prix>
    <comment> Un commentaire </comment>
  </produit>
  <produit>
    <nom> CD </nom><prix monnaie="Euros"> 23 </prix>
  </produit>
  <!-- Texte -->
</stock>

Les expressions

La forme générale d'une expression XPATH est


sélecteur1/sélecteur2/...      (exp. relative)
/sélecteur1/sélecteur2/...      (exp. absolue)

Chaque sélecteur sélectionne un ensemble de noeuds en fonction du résultat du sélecteur précédent.

L'ensemble initial est soit le noeud courant (forme relative) soit la racine (forme absolue).

Exemple:

/stock/produit/comment

Les sélecteurs de noeuds

Les sélecteurs de noeuds sont de la forme :

axe::filtre[condition1][condition2]...

Les parties « axe » et « conditions » sont optionnelles.

Les axes de recherche

Les axes en avant

Les axes qui permettent de descendre dans l'arbre:

child            
les fils du noeud courant (c'est l'axe par défaut). C'est deux expressions sont identiques :
produit/child::nom
produit/nom
self            
le noeud courant,
/stock/produit[condition1]/self::produit[condition2]
descendant            
les descendants du noeud courant
/stock/descendant::prix
descendant-or-self            
les descendants du noeud courant plus lui-même.

Les axes en arrière

Les axes qui permettent de remonter dans l'arbre:

parent            
le noeud parent du noeud courant,
ancestor            
les ascendants du noeud courant (dans l'exemple ci-dessous le noeud courant est le nom du produit) :
ancestor::produit/prix
ancestor-or-self            
que dire ?

Les axes à droite et à gauche

following-sibling            
les noeuds frères placés après le noeud courant,
img-xpath/axe-following-sibling.png
preceding-sibling            
les noeuds frères placés avant le noeud courant,

Les axes avant et après

following            
les noeuds placés après dans le document,
img-xpath/axe-following.png
preceding            
les noeuds placés avant dans le document,

Les axes pour les attributs

attribute            
les noeuds de type attribut du noeud courant,
namespace            
les noeuds de type espace de nom du noeud courant,

Les filtres

Filtrer les noeuds nommés

nom            
les noeuds de l'axe qui portent ce nom.
/stock/produit/prix/attribute::monnaie
*            
les noeuds de l'axe qui ont un nom.
/stock/*/prix/attribute::*

Filtrer les noeuds textuels

text()            
tous les noeuds de type texte de l'axe.
/stock/produit/*/text()

Filtrer les commentaires

comment()            
tous les noeuds de type commentaire de l'axe.

Filtrer les instructions de traitement

processing-instructions()            
tous les noeuds de type instruction de traitement de l'axe,

Filtrer les noeuds

node()            
tous les noeuds de l'axe sauf la racine,
/stock/produit/prix/node()
id(label)            
le noeud repéré par une étiquette,
id('CD')/prix

Les conditions

Rappel : les sélecteurs de noeuds sont de la forme :

axe::filtre[condition1][condition2]...

Condition d'existence

expression-xpath            
vraie ssi l'expression renvoie un ensemble non vide de noeuds.
/stock/produit[prix/attribute::monnaie]
/stock/produit[prix[attribute::monnaie]]
Ces expressions sélectionnent les noeuds produit à condition qu'un prix existe avec l'attribut monnaie précisé.

Condition de position

numéro            
vraie ssi le noeud courant à cette position dans le contexte courant.
produit[2][comment]
produit[comment][2]
La première expression sélectionne les noeuds produit en deuxième position si il possède un élément fils comment, la seconde sélectionne le deuxième noeud produit qui possède un élément fil comment.

Les conditions logiques

expr-xpath1 relation expr-xpath2            
vraie ssi il existe n1 (dans le résultat de expr-xpath1) et n2 (dans le résultat de expr-xpath2) qui respectent la relation. les relations possibles sont =, !=, <, <=, >, >=.
produit[prix = 100]                      (1)
produit[prix != 100]                     (2)
produit[prix <  /stock/produit/prix]     (3)
Explications : (1) les produits qui ont un prix à 100 ; (2) les produits qui ont un prix différent de 100 ; (3) tous les produits sauf les plus onéreux.
condition1 and condition2            
vraie ssi les deux conditions le sont également.
produit[prix > 10 and comment]
condition1 or condition2            
vraie ssi au moins une des deux conditions est vraie.
not(condition)            
vraie ssi la condition est fausse.
produit[not(prix != 100)]
tous les prix sont égaux à 100.

Fonctions & opérations

Les fonctions et opérations sont utilisables dans

Opérations sur les nombres

type de base            
booléen, chaîne de caractères, nombre réel, ensemble de noeuds.
+, -, mod, div,             
opérations utilisables sur les nombres (traduction automatique).
produit[(prix div 10) = (prix mod 10)]

Fonctions sur les nombres

number(object)            
traduire l'objet sous la forme d'un nombre. renvoie NaN si l'objet ne représente pas un nombre.
sum(noeuds)            
renvoie la somme des noeuds après les avoir transformés en nombre.
count(noeuds)            
renvoie le nombre de noeuds.
floor(nombre)            
arrondi par le bas.
ceiling(nombre)            
arrondi par le haut.
round(nombre)            
arrondi par le plus proche.

Fonctions sur les booléens

true()            
toujours vraie.
false()            
toujours fausse.
boolean(objet)            
vraie ssi l'objet est égale à la constante « true ».
not(booléen)            
vraie ssi le paramètre est faux.

Fonctions sur les noeuds

last()            
vraie ssi le noeud est le dernier du contexte courant.
position()            
renvoie la position dans le contexte du noeud courant.
local-name(noeuds)            
renvoie la partie locale de l'étiquette d'un noeud.
namespace-uri(noeuds)            
renvoie la partie espaces de nom de l'étiquette d'un noeud.
name(noeuds)            
renvoie l'étiquette d'un noeud.
id(nom)            
renvoie le noeud identifié par l'étiquette nom.

Fonctions sur les chaînes

string(objet)            
renvoie une version chaîne du paramètre.
concat(chaîne1,...,chaîneN)            
concaténation de chaînes.
string-length(chaîne)            
renvoie la longueur d'une chaîne.
normalize-space(chaîne)            
renvoie une version normalisée (suppression des blancs au début et à la fin et remplacement de toute suite de blancs par un seul).
translate(ch1,ch2,ch3)            
renvoie une chaîne construite à partir de ch1 dans laquelle les caractères présents dans ch2 sont remplacés par les caractères de même position dans ch3.
substring-before(ch1,ch2)            
renvoie la chaîne res définie par ch1 = res + ch2 + reste.
substring-after(ch1,ch2)            
renvoie la chaîne res définie par ch1 = reste + ch2 + res.
substring(chaîne,début) et substring(chaîne,début,len)            
extraction de sous-chaîne.
starts-with(ch1,ch2)            
vraie ssi ch1 débute par ch2.
contains(ch1,ch2)            
vraie ssi ch1 contient ch2.

Simplifications

Afin d'éviter une trop grande lourdeur, les simplifications suivantes sont autorisées :

originale simplifiée exemple
child:: /stock/produit
attribute:: @ /prix/@monnaie
/descendant-or-self::node()/ // //prix
self::node() . prix[. = 10]
parent::node() .. prix/../nom
[position() = x] [x] produits[4]