Programmation XML/XPath
Syntaxe
modifierLe 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. |
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 :
- Un axe (parent, descendant…).
- Un test de nœud (nom ou fonction désignant les nœuds).
- Des prédicats (entre crochets).
Axes
modifierPour 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
modifierSoit l'espace de nom ns
:
//ns:*
sélectionne tous 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
modifierLes 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
modifierSoit 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- Sélection 1 : toutes les <feuille> d'une <brindille> contenue dans une <branche>, descendant du <tronc>, issu de la racine.
- Abrégé :
/tronc/branche/brindille/feuille
- Non abrégé :
/child::tronc/child::branche/child::brindille/child::feuille
- Abrégé :
- Sélection 2 : la <branche> dont l'attribut "nom" est "branche3", enfant du <tronc>, inclue dans la racine.
- Abrégé :
/tronc/branche[@nom='branche3']
- Non abrégé :
/child::tronc/child::branche[attribute::nom='branche3']
- Abrégé :
- Sélection 3 : toutes les brindilles ont au moins une feuille.
//brindille[feuille]
- Sélection 4 : dernière branche du tronc.
//tronc/branche[last()]
- Sélection 5 : tous les noms des brindilles qui n'ont pas de feuille.
//brindille[not(feuille)]/@nom
PHP
modifierCré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.");
?>
- Pour plus de détails voir : XQuery.
Références
modifierVoir aussi
modifier- http://b3d.bdpedia.fr/query.html#s1-xpath-trouver-son-chemin-xml : explications avec vidéo en français