Xpath avec PHP

 
 

Les applications utilisant XML sont partout ! Que ce soit les fils d’actualités en RSS, les services web ou les formats de stockage (OpenDocument pour LibreOffice et OpenXML pour MsOffice) il est difficile d’y échapper. Le premier objectif d’XML est atteint : ouverture et interopérabilité.

Notre objectif à travers cet article va être de découvrir ce qui est communément vu comme la cerise sur le gâteau XML : Xpath le moteur de recherche du XML.

XML et XPath ?

Comment faire une recherche dans votre document XML ? Comment accéder aux données de façon aussi simple qu’avec SQL ? La solution existe : XPath !
C’est le nom d’une syntaxe permettant de faire des recherches ou sélections dans un document XML. Il s’agit donc d’un moyen d’accéder aux données très simple dans l’univers XML.

Comment l’utiliser ?

Nous allons baser nos exemples sur la plate-forme principale d’applications Web : PHP. Comme Xpath est une spécification du W3C vous pourriez également l’utiliser avec d’autres plates-formes. Nous
préférerons PHP 5 qui offre, avec SimpleXML, des fonctionnalités de traitement des fichiers XML extrêmement puissantes et faciles d’accès. Avec PHP il est possible d’utiliser Xpath au travers :
– des fonctionnalités DOM,
– des fonctionnalités SimpleXML

Si DOMDocument permettait déjà de parcourir l’arbre DOM noeud par noeud et d’utiliser de façon complexe XPath, SimpleXML gère le document XML dans sa globalité, en tant qu’objet. L’extension
SimpleXML implémente une méthode xpath(). Cela nous permet d’utiliser cette méthode d’accès à des arbres DOM, donc à tout document XML ou XHTML.

Comment accéder aux éléments ?

Xpath voit un document XML comme un arbre de noeuds.
Nous nous intéresserons aux noeuds de trois types :
– les noeuds d’éléments, c’est-à-dire les balises XML
– les noeuds d’attributs, qui ajoutent des informations aux balises
– les noeuds de texte, les données du document
Notez que simpleXML propose déjà des méthodes pour accéder aux éléments et attributs.

La syntaxe XPath appliquée à la recherche d’éléments

Il existe deux syntaxes pour noter le chemin à travers les éléments du DOM XML :
– la méthode complète, qui garantit le moins d’erreurs possibles et le plus de précision,
– la méthode abrégée qui est plus rapide à écrire.
Considérons les balises XML suivantes et cherchons à désigner l’élément  » c « .

<a>
<b>
<c></c>
<c></c>
<c></c>
</b>
</a>

En utilisant la notation complète on aurait : a/child::b/child::c
En utilisant la notation abrégée on aurait : a/b/c

A retenir : on sépare les éléments imbriqués les uns dans les autres par un slash, comme les répertoires Unix. On sépare les mots-clés de désignation du nom de l’élément par ::

1. Arborescence des noeuds :
Pour accéder au noeud racine, on peut utiliser le signe /
Pour désigner le noeud sur lequel on travaille, on utilise la notation ./
Pour désigner le noeud parent, on utilise la notation ../

2. Désigner plusieurs noeuds à la fois :
Les caractères spéciaux permettent de choisir plusieurs éléments en une seule notation. On utilise l’étoile * comme caractère joker, et // pour outrepasser la désignation de l’arborescence.
Soit le XML suivant :

<a>
<b>
<c></c>
<c></c>
<c></c>
</b>
</a>
<a>
<b>
<c></c>
<c></c>
<c></c>
</b>
</a>
<a>
<b>
<c></c>
<c></c>
<c></c>
</b>
<c></c>
<c></c>
</a>

 

Je désigne tous les noeuds enfants de a par a/* (je récupère donc les noeuds b et c). Je désigne tous les c contenus dans un élément b par b//c, si je souhaite au contraire tous les éléments c quel que soit le noeud parent, je ferais //c

Attention, on postule que la DTD autorise des éléments c qui ne seraient pas dans . On peut également combiner les choix dans les fonctions par le caractère | (pipe).

La syntaxe XPath appliquée à la recherche d’attributs

La notation longue des attributs se fait par le mot clef attribute, et la notation abrégée par le caractère @.

<personne>
<yeux couleur = »bleu »>
</yeux>
<cheveux couleur= »blond »>longs</cheveux>
</personne>
<personne>
<yeux couleur = »gris »>
</yeux>
<cheveux couleur= »blond »>en brosse</cheveux>
</personne>
<personne>
<yeux couleur = »brun »>
</yeux>
<cheveux couleur= »noir »>courts</cheveux>
</personne>

Pour désigner les attributs de couleurs d’yeux, je note :
/child::personne/child::yeux/attribute::couleur (complète)
/personne/yeux/@couleur (abrégée)

La syntaxe XPath appliquée à la recherche de texte

On utilise la fonction contains(chaine, motif ). Depuis PHP, notre chaîne sera le titre de la nouvelle qu’on souhaite examiner. On peut examiner aussi bien les noeuds que leurs attributs, que le texte contenu dans le noeud élément.

Syntaxe d’un flux RSS 2.0 dans du XML

Un flux RSS est en XML et obéit à une norme. On sait donc que tous les flux RSS 2.0 auront la structure suivante :

<rss version= »2.0″>
<channel>
<title>Titre du channel</title>
<link>http://www.monsite.com</link>
<description>Description du channel</description>
items…
</channel>
</rss>

Cas d’application : afficher les titres de flux RSS contenant le mot PHP Imaginons qu’on ait un grand nombre de flux RSS (par exemple, 2000) et qu’on ne souhaite afficher que les nouvelles concernant PHP. On va donc n’être intéressé que par les titres contenant le mot clef « PHP ».


// Définition des sources
$tablo_flux[] = 'http://www.afup.org/backend.php3';
$tablo_flux[] = 'http://www.nexen.net/index2.php?option=com_rss&feed=RSS0.91&no_html=1';
$tablo_flux[] = 'http://news.google.fr/news?ned=fr&topic=t&output=rss';
// On récupère le mot clef recherché dans l'URL
$mot = ['PHP'];
$taille = count($tablo_flux);
for( $i=0 ; $i < $taille ; $i++ ){ $racine[$i] = simplexml_load_file($tablo_flux[$i]); $recherche = "/rss/channel/item[contains(title,'$mot')]"; $titres = $racine[$i]->xpath($recherche);
if($titres){
foreach($titres as $actu){
$lien = htmlentities((string)$actu->link);
$titre = utf8_decode($actu->title);
echo '<tr><td><a href=$lien>$titre</a></td></tr>';
}
}
}

Cet exemple simple permet de montrer comment faire une recherche simple dans des fluxs rss. Rien ne vous empêche d’aller plus loin et de créer un système de veille sur un ou plusieurs sujets qui vous intéressent.

Nos formations PHP pour débuter

Formation à Symfony 6™

Formation pour prendre en main Symfony

  • Spécialisation PHP
  • 3 jours - 21h
  • 1800€