XPath

Un article de Mangue.org, l'encyclopéde libre.


Sommaire

XPath, un langage de requêtes


Tout comme XML, c'est un standard soutenu par le W3C (http://www.w3.org/), vous pouvez donc trouver le texte complet des recommandations concernant Xpath sur la page http://w3.org/TR/xpath . Il s'agit d'un langage de requêtes afin de questionner les documents XML. La syntaxe de des requêtes est documentée et standardisée et ne varie donc pas selon les parseurs utilisés. Il sera donc très rapide de passer d'une API à une autre ou même de changer de langage pour les traiter.


Une requête Xpath ressemble beaucoup à un chemin de fichiers. En effet, Comme nous l'avons vu dans l'introduction au XML, un tel document est représenté par un arbre. Il a donc un élément racine et des branches ; à l'intersection de deux branches, on trouve des noeuds. Pour repérer un élément dans un document XML, il suffit donc de donner le chemin complet de la racine de l'arbre jusqu'à l'élément. Comme sur les systèmes unixoïdes, la racine se note "/" ; pour écrire un chemin avec XPath, les éléments sont séparés par des barres obliques "/" (slash).


Reprenons l'exemple de document XML, que nous avons utilisé dans l'introduction :


<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!-- Balise racine -->
<livre>
	<titre>Xml, XPath &amp; Xslt</titre>
	<!-- Premier chapitre -->
	<chapitre titre="Introduction à l'XML">
		<texte>
			eXtensible Markup Language
			5 &gt; 3
		</texte>
	</chapitre>
 
	<!-- Deuxième chapitre -->
	<chapitre titre="Presentation de Xslt">
		<texte>Pour formater un fichier XML</texte>
	</chapitre>
</livre>


Par exemple, la requête :


/livre/chapitre/texte


renverra les éléments contenus dans les balises , tandis que la requête :


/livre/chapitre[@titre]/text()


renverra tous les titres des chapitres du livre. Afin de préciser les choses et de rentrer plus avant dans les possibilités d'XPath, le tableau ci-dessous donne des exemples simples de requêtes XPath, ainsi que leur résultat.


Requête XPath Résultat de la requête (sélection)
/livre élément livre racine du document
./texte éléments texte du noeud courant
texte éléments texte du noeud courant
../texte éléments fils texte du noeud parent
* tous les éléments fils du noeud courant
../* tous les éléments au niveau du noeud parent (Y compris le noeud courant)
//texte tous les éléments texte, quelque soit leur position dans l'arbre.
chapitre/texte tous les éléments texte de tous les noeuds chapitres du noeud courant


Lorsque l'on veut accéder aux attributs d'un élément XML, on fait précéder le nom de l'attribut d'un arobase, «@».


Requête XPath Résultat de la requête (sélection)
texte/@type attribut type de tous les élements texte du noeud courant
texte/@* tous les attributs de tous les élements texte du noeud courant
*/@titre tous les noeuds courants qui ont un attribut titre


Comme vous l'avez sans doute remarqué l'étoile « * » est un caractère «joker», qui peut prendre toutes les valeurs possibles, l'étoile peut remplacer un nombre illimité de caractères ou même aucun.


Les axes


Les axes indiquent la direction d'un chemin. Les requêtes, qui ont déjà été présentées utilisent de manière implicite certains axes. Par exemple les deux points «..» font référence au noeud parent. Ceci correspond à l'axe Ancestor. Pour préciser un axe dans une requête XPath il suffit d'indiquer le type de l'axe suivit de deux symoboles « deux points » et du ou des noeuds à sélectionner : Axe::noeud.


Axe Définition
Ancestor noeuds parents du noeud courant
ancestor-or-self noeud courant ET ses noeuds parents
attribute attributs du noeud courant
child noeuds fils du noeud courant
descendant noeuds fils des noeuds fils
descendant-or-self noeud courant ET ses noeuds fils (//)
following noeuds après le noeud courant
namespace noeuds espace de nom du noeud courant
following-sibling noeuds frères après le noeud courant
preceding noeuds avant le noeud courant
self noeud courant (.)


Ainsi, on peut très bien écrire la même requête de différentes manières. Par exemple, les requêtes suivantes sont équivalentes :


child::chapitre <=> chapitre <=> ./chapitre


Toujours à titre d'exemple, preceding::* sélectionne tous les noeuds précèdant le noeud courant.


Les prédicats


Les prédicats permettent de rajouter des conditions à une requête XPath. En effet, il est souvent nécessaire de sélectionner des éléments en fonction de leur position dans l'arbre XML ou bien de la valeur d'un ou plusieurs de ses attributs, etc. Ce sont donc des filtres, que l'on rajoute à une expression XPath. Chaque prédicat doit être entouré de crochets. Il est également possible d'insérer plusieurs prédicats dans une expression XPath.


Prédicat Sélection
chapitre[texte] éléments chapitre comportant un élément texte
chapitre[@titre='XPath'] éléments chapitre comportant un un attribut titre avec la valeurs 'XPath'
chapitre[3] élement chapitre à la 3eme position du document
chapitre[6][texte] sixième élement chapitre du noeud courant s'il comporte un élément texte


Pour affiner des requêtes Xpath, il est possible d'utiliser des opérateurs dans un prédicat.


Opérateur XPath Définition
= Égalité
!= différence
> supérieur
< inférieur
>= Supérieur ou égal
<= Inférieur ou égal
and « ET » logique
or « ou » logique
Not() Négation logique
+ addition
- soustraction
div Division
mod Reste de la division entière (modulo)


Voici un prédicat, qui sélectionne tous les noeuds chapitre du noeud courant ayant leur id supérieur à 3


chapitre[@id>3]


Les fonctions XPath


Pour permettre des requêtes XPath toujours plus subtiles et précises on peut avoir recours aux fonctions internes de XPath. Il existe 4 catégories de fonctions :


  • fonctions pour les noeuds
  • fonctions pour les chaînes de caractères
  • fonctions pour les booléens
  • fonctions pour les nombres


En les combinant avec des prédicats elles permettent d'appliquer des filtres très fins aux requêtes XPath et d'obtenir des informations suplémentaires sur un noeud tel que son espace de nom ou encore sa position.


Fonctions sur les noeuds Définitions
count(noeuds) Retourne le nombre de noeuds
id(id) Renvoie le noeud ayant l'identifiant id
last() Renvoie true si le noeud est courant est le dernier
local-name(noeuds) Renvoie les noms des noeuds sans l'espace de nom
name(noeuds) Renvoie le nom complet
namespace-uri(noeuds) Renvoie l'uri de l'espace de nom.


Fonctions sur les chaines de caractères Définitions
concat(chaine, chaine, ...) Concatène les chaines de caractères
contains(chaine1, chaine2) Retourne vrai si la chaine1 contient la chaine2
normalize-space(chaine) Remplace les blancs multiples par un unique espace et suprime les espaces des extrémités sont suprimés
start-with(chaine1, chaine2) Retourne vrai si la chaine1 commence avec les même caracrères de que la deuxième
string(var) Retourne var sous forme d'une chaine de caracrères
string-lenght(chaine) Retourne la longueure de la chaine
substring(chaine, offset, lenght) Retourne la sous-chaine en fonction de l'offset et de la longueur


Fonctions sur les booléens Définitions
boolean(var) Convertit var en un booléen
not(var) Retourne la négation de var
true() Retourne vrai
false() Retourne faux
lang(chaine) Indique si chaine est de la langue du document


Fonctions sur les nombres Définitions
number(var) Convertit var en un nombre
sum(noeuds) Retourne la somme des noeuds
floor(var) Retourne le plus petit entier inférieur ou égal à var
ceiling(var) Retourne le plus petit entier supérieur ou égal à var
round(var) Retourne var sous forme d'entier le plus proche


XSLT ajoute de nouvelles fonctions à XPath toutes aussi interressantes et qui offrent encore plus de possibilités. En effet il est possible d'interroger un autre document XML à partir d'une feuille de style grâce à la méthode document.


Exemples et test de Requêtes XPath


Nous allons étudier plusieurs exemples de requêtes XPath sur le document XML utilisé au début de ce tutoriel. Pour cela, nous allons utiliser un script Perl qui prend en argument (sur la ligne de commande) le chemin vers un fichier XML et une requête XPath, celui-ci renverra alors le résultat de la requête XPath appliquée au fichier XML.


Ce script peu s'avérer très utile pour tester des requêtes lors de la phase de développement d'un projet ou tout simplement pour bien comprendre comment fonctionnent les requêtes Xpath. Voici donc le code du script Perl TestRequete.pl . Il ne s'agit pas ici d'expliquer son fonctionnement, pour cela reportez vous à la documentation de Perl et de son module de gestion de XPath : XML::XPath disponible sur le CPAN (http://www.cpan.org/).


#!/usr/bin/perl 
 
use XML::XPath; 
use XML::XPath::XMLParser; 
use strict; 
 
# On récupère le nom du fichier XML et on le charge. 
my $xpath = XML::XPath->new( filename => shift @ARGV ); 
 
# On applique la requête XPath passée en argument. 
my $nodeset = $xpath->find( shift @ARGV ); 
 
#On affiche le résultat 
foreach my $node ( $nodeset->get_nodelist ) { 
    print XML::XPath::XMLParser::as_string( $node ) . "n"; 
}


Nous allons maintenant voir quelques requêtes, qui pourrait servir pour la consultation d'un livre stocké sous la forme d'un document XML semblable à celui que nous avons vu. Pour consulter le titre du livre, la requête :


/livre/titre


renvoie


<titre>Xml, XPath & Xslt</titre>


et la requête


/livre/titre/text()


renvoie


Xml, XPath & Xslt


Pour compter le nombres de chapitres, on utilise la fonction Xpath count() pour les titres, il faut accéder à l'attribut titre des balises chapitre, on a donc les deux requêtes suivantes :


count( /livre/chapitre )
/livre/chapitre/@titre


Si on veut donner un aperçu de chaque chapitre, on peut aussi en présenter le début (les 100 premiers caractères par exemple), ceci se fait grâce à la fonction substring :


substring( /livre/chapitre/texte[1], 1, 100 )


Une fois toutes les informations récupérées il ne reste plus qu'à tout mettre en forme pour consulter le sommaire. Ceci peut se faire grâce à un programme développé par vos soins via l'API pour XML et XPath du langage que vous avez choisi. Cependant, il est également possible d'avoir recours aux transformations XSLT, qui permettent d'utiliser des requêtes Xpath dans les feuilles de style XSL.


Liens externes


Outils personels