TUTORIEL PHP 
PHP5 : SimpleXML
SimpleXML est une des deux nouvelles extensions de PHP 5 consacrées à XML, et présente une approche du traitement des fichiers XML mettant en avant la simplicité d'utilisation. (22/09/2004)

(fourni par Direction PHP)

<< 1. Introduction
2. Analyse du code XML
3. Accès aux données XML et aux attributs
4. SimpleXML et XPath
5. Recherche de balise et gestion des espaces de noms

Recherche de balises
Il est aussi possible de faire des recherches sur tout le document XML, pour obtenir le contenu des balises portant un certain nom. Dans certaines situations où les balises sont dispersées dans tout le document, c'est une fonction précieuse pour les rassembler. La méthode xpath() se charge alors d'analyser l'arbre et de retourner un tableau d'éléments SimpleXML.

<?php
$string = <<<XML
<a>
  <b>
    <c>autre texte</c>
    <c>
      <d>texte</d>
      <d>texte2</d>
    </c>
    <c>
      <d>texte3</d>
      <d>texte4</d>
    </c>
  </b>
  <d id= '33'>
    <c>contenu</c>
  </d>
</a>
XML;
$xml = simplexml_load_string($string);

/* On cherche les balises d */
$result = $xml->xpath('//d');

print_r($result);
?>


Par rapport à l'exemple précédent, vous pouvez remarquer les deux anti-slash qui débutent la recherche. On indique ici au moteur XPath que l'on recherche les balises D, et non pas qu'on veut traiter une sous-partie de l'arborescence.

Pour rechercher plusieurs balises différentes, vous pouvez les séparer par un seul anti-slash, comme ceci :
//d/c/a

Gestion des espaces de noms
SimpleXML supporte les espaces de noms de manière très simple. La notation $balise_mere->$balise_fille ne peut pas être utilisée avec les espaces de noms, car il faudrait un moyen de les configurer : cela éloignerait SimpleXML de son objectif de simplicité. A la place, les concepteurs de l'extension proposent de passer un argument optionnel aux méthodes children() et attributes(). Voyons comment cela se passe.

Dans le cadre de notre article, nous allons utiliser un fichier RSS disponible sur nexen.net, et qui contient l'actualité PHP et MySQL du jour. Voici son adresse : http://www.nexen.net/news/backend.1.rss

Voici un extrait du contenu :
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- generator="FeedCreator 1.6" -->
<rdf:RDF
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel rdf:about="http://www.nexen.net/news/backend.1.rss">
    <title>PHP news</title>
    <description>ActualitŽ Nexen.net : PHP &amp; MySQL</description>
    <link>http://www.nexen.net/news/</link>
    <image rdf:resource="http://goodies.nexen.net/img/logo_88x31.gif" />
    <dc:date>2004-08-10T18:41:19+00:00</dc:date>
    <items>
      <rdf:Seq>
        <rdf:li rdf: resource="http://www.nexen.net/news/
gen.php/2004/08/10/3331,0,0,0,0.php" />
        <rdf:li rdf:resource="http://www.nexen.net/news/
gen.php/2004/08/10/3330,0,0,0,0.php"/>
        <rdf:li rdf:resource="http://www.nexen.net/news/
gen.php/2004/08/10/3329,0,0,0,0.php"/>
        <rdf:li rdf:resource="http://www.nexen.net/news/
gen.php/2004/08/10/3328,0,0,0,0.php"/>
      </rdf:Seq>
    </items>
  </channel>
  <image rdf:about="http://goodies.nexen.net/img/logo_88x31.gif">
    <title>nexen.net</title>
    <link>http://www.nexen.net</link>
    <url>http://goodies.nexen.net/img/logo_88x31.gif</url>
  </image>
  <item rdf:about="http://www.nexen.net/news/
gen.php/2004/08/10/3331,0,0,0,0.php">
    <dc:format>text/html</dc:format>
    <dc:date>2004-08-10T17:36:36+00:00</dc:date>
    <title>&quot;echo&quot; : lapin ou tortue ?</title>
    <link>http://www.nexen.net/news/
gen.php/2004/08/10/3331,0,0,0,0.php</link>
    <description>Cet article fait le point sur les performances de &quot;echo&quot; lorsque l'on utilise la concaténation ou les paramètres multiples.</description>
  </item>
</rdf>


On remarque dès le début du fil de dépêches la présence de trois espaces de noms, spécifiés dans la balise RDF initiale. Par exemple,
xmlns:dc="http://purl.org/dc/elements/1.1/"
indique que l'espace de nom dc repose sur des spécifications définies par l'URL indiquée. Dans le corps de notre fil de dépêches, nous retrouvons des balises de cette forme : <dc:date>. Cette balise fait partie de l'espace de noms dc. Les balises qui ne sont pas préfixées par un espace de noms font alors partie de l'espace de noms global.

Pour accéder aux balises disponibles dans la balise channel, on utilise le code suivant :

<?php
$rss = simplexml_load_file('http://www.nexen.net/news/backend.1.rss');
foreach ($rss->channel as $c) {
  foreach ($c->children() as $tag => $item) {
    printf("balise : %s\n", $tag);
    }
  }
?>


Le script affiche :

Balise : title
Balise : description
Balise : link
Balise : image
Balise : items

En observant de plus près, nous nous apercevons qu'il manque la balise date. Cette dernière fait partie de l'espace de nom dc, puisqu'elle est précédée par dc:. Pour y accéder, il nous faut préciser aussi cet espace de nom. L'exemple précédent devient :

<?php
$rss = simplexml_load_file('http://www.nexen.net/news/backend.1.rss');
foreach ($rss->channel as $c) {
  foreach ($c->children('http://purl.org/dc/elements/1.1/') as $tag => $item) {
    printf("Balise : %s\n", $tag);
    }
  }
?>


Balise : date

Théoriquement, nous pourrions utiliser aussi le nom 'dc' pour sélectionner les balises de channel qui font partie de l'espace de noms 'http://purl.org/dc/elements/1.1/'. Toutefois, il semble que cette fonctionnalité ne soit pas totalement implémentée, et nous n'avons pas pu la faire fonctionner dans cet exemple. Peut-être cela sera-t-il corrigé pour PHP 5.1 ?

L'utilisation des espaces de noms est identique pour les attributs et la méthode attributes() :

<?php
$rss = simplexml_load_file('http://www.nexen.net/news/backend.1.rss');
foreach ($rss->channel as $c) {
  foreach ($rss->channel->attributes('http://www.w3.org/1999/02/22-rdf-syntax-ns#') as $tag => $item) {
    printf("Attribut RDF : %s\n", $tag);
    }
  print $rss->channel['about']."\n";
  }
?>


Attribut RDF : about
About

En précisant l'espace de nom rdf, nous avons obtenu les identifiants de cet espace.

Si nous souhaitons obtenir tous les identifiants, quel que soit leur espace de nom, alors la notation $balise['attribut'] est toujours disponible, et recense tous les identifiants. De même, la notation $balise->sous_balise et $balise->sous_balise[] donne accès à toutes les balises détectées, indépendamment de leur espace de noms. Le plus important est que l'ensemble reste simple et souple à utiliser.

<< 1. Introduction
2. Analyse du code XML
3. Accès aux données XML et aux attributs
4. SimpleXML et XPath
5. Recherche de balise et gestion des espaces de noms
 
Rédaction JDN Développeurs
 
Accueil | Haut de page
 
 





Quand achetez-vous le plus en ligne ?
Du lundi au vendredi
Le samedi
Le dimanche

Tous les sondages