Programmation XML/XPath

Un livre de Wikilivres.

Syntaxe[modifier | modifier le wikicode]

Le XPath est un langage de sélection de différents types d'objets XML, appelés « nœuds »[1]. Un ensemble de nœuds est appelé « contexte ».

Le XPath se présente sous la forme de chemins composés de[2] :

Sélecteur Notes
nom du nœud Sélectionne ce qui est compris dans le nœud nommé.
/ Sélectionne en partant du nœud racine (chemin absolu).
// Sélectionne en partant du nœud courant, peu importe le reste de l'emplacement.
. Sélectionne à partir du nœud courant (chemin relatif). = self::node()
.. Sélectionne à partir du parent du nœud courant. = parent::node()
@ Sélectionne les attributs. = attribute::
| Opérateur de sélection multiple.
 Il existe un interpréteur en ligne pour réaliser les exemples décrits ci-dessous : http://www.xpathtester.com/.
La classe http://www.php.net/manual/fr/domxpath.query.php permet de les programmer.

Ces expressions sont appelées « chemin de localisation », composés d'un ou plusieurs « pas de localisation » (ou « étapes ») séparés par des « / ». Les pas de localisation ont chacun trois composants :

  1. Un axe (parent, descendant…).
  2. Un test de nœud (nom ou fonction désignant les nœuds).
  3. Des prédicats (entre crochets).

Axes[modifier | modifier le wikicode]

Pour décrire les relations entre les nœuds, XPath utilise le vocabulaire suivant :

Axe Abréviation Notes
ancestor ancêtre
ancestor-or-self ancêtre ou soi
attribute @ attribut, @abc signifie attribute::abc
child enfant, xyz signifie child::xyz
descendant
descendant-or-self // // signifie /descendant-or-self::node()/
following suivant
following-sibling frère suivant
namespace espace de noms
parent .. .. signifie parent::node()
preceding précédent
preceding-sibling
self . soi, . signifie self::node()

Tests de nœuds[modifier | modifier le wikicode]

Soit l'espace de nom ns :

  • //ns:* sélectionne tout les éléments du namespace.
  • //ns:nom récupère tous les éléments du namespace nommés "nom".
Tests Notes
comment() trouve tous les commentaires (ex : <!-- commentaire 1 -->)
text() trouve un nœud texte, (ex : hello world dans <k>hello<m> world</m></k>)
processing-instruction() trouve les instructions de traitement (ex : //processing-instruction('php') trouve <?php echo $a; ?>)
node() trouve tous les nœuds.

Prédicats[modifier | modifier le wikicode]

Les prédicats sont des fonctions filtrant les nœuds évalués à false, qui se placent à la fin des sélections[3] :

Par exemple, les quatre requêtes ci-dessous renvoie le même résultat (si la branche 2 est la dernière comme dans l'exemple en bas de cette page) :

//branche[2]
//branche[@nom="branche2"]
/tronc/branche[last()]
/tronc/branche[position()=2]
Prédicats Notes
last() renvoie le dernier nœud de la sélection
position() renvoie le nœud situé à la position précisée
count(contexte) renvoie le nombre de nœuds en paramètre
starts-with(chaine1, sous-chaine2) renvoie true si le premier argument commence avec le second
contains(botte_de_foin, aiguille) renvoie true si le premier argument contient le second
sum(contexte) renvoie la somme des valeurs numériques des nœuds en paramètre
floor(nombre) renvoie le nombre arrondi à l'entier inférieur
ceiling(nombre) renvoie le nombre arrondi à l'entier supérieur
round(nombre) renvoie le nombre arrondi à l'entier le plus proche

Exemples[modifier | modifier le wikicode]

Soit l'arborescence suivante :

<?xml version="1.0" encoding="UTF-8"?>
<tronc nom="tronc1"> 
	<!-- commentaire 1 --> 
	<branche nom="branche1" epaisseur="gros"> 
		<brindille nom="brindille1"> 
			<!-- commentaire 2 --> 
			<feuille nom="feuille1" couleur="marron" />
			<feuille nom="feuille2" poids="50" />
			<feuille nom="feuille3" /> 
		</brindille> 
		<brindille nom="brindille2">
			<feuille nom="feuille4" poids="90" /> 
			<feuille nom="feuille5" couleur="violet" />   
		</brindille>
	</branche> 
	<branche nom="branche2">
		<brindille nom="brindille3"> 
			<feuille nom="feuille6" /> 
		</brindille> 
		<brindille nom="brindille4">	
			<feuille nom="feuille7" /> 
			<feuille nom="feuille8" /> 
			<feuille nom="feuille9" couleur="noir" /> 
			<feuille nom="feuille10" poids="100" />	 
		</brindille>
	</branche> 
	<branche nom="branche3">
		<brindille nom="brindille5"> 
		</brindille> 
	</branche> 
</tronc>

Abréviations[modifier | modifier le wikicode]

  • Sélection 1 : toutes les <feuille> d'une <brindille> contenue dans une <branche>, descendant du <tronc>, issu de la racine.
    1. Abrégé : /tronc/branche/brindille/feuille
    2. Non abrégé : /child::tronc/child::branche/child::brindille/child::feuille
  • Sélection 2 : la <branche> dont l'attribut "nom" est "branche3", enfant du <tronc>, inclue dans la racine.
    1. Abrégé : /tronc/branche[@nom='branche3']
    2. Non abrégé : /child::tronc/child::branche[attribute::nom='branche3']
  • Sélection 3 : toutes les brindilles ont au moins une feuille.
    1. //brindille[feuille]
  • Sélection 4 : dernière branche du tronc.
    1. //tronc/branche[last()]
  • Sélection 5 : tous les noms des brindilles qui n'ont pas de feuille.
    1. //brindille[not(feuille)]/@nom

PHP[modifier | modifier le wikicode]

Créer le .php suivant à côté du tronc.xml publié ci-dessus.

<?php
  $file = 'tronc.xml';
  $xpath = "/tronc/branche/brindille/feuille[last()]";
  if(file_exists($file)) {
    $xml = simplexml_load_file($file);
    if($result = $xml->xpath($xpath)) {
		print 'Résultats :';
		var_dump($result);
    } else {
      echo 'Syntaxe invalide.';
	}
  }
  else
    exit("Le fichier $file n'existe pas.");
?>

eXist ou BaseX[modifier | modifier le wikicode]

Pour plus de détails voir : XQuery.

Références[modifier | modifier le wikicode]

  1. http://www.w3schools.com/dom/dom_nodetype.asp
  2. http://www.w3schools.com/xpath/xpath_syntax.asp
  3. http://www.w3.org/TR/xpath#corelib

Voir aussi[modifier | modifier le wikicode]