Les fonctions XML supportant de la librairie expat de James Clark, permettent d'analyser et non de valider des documents XML subséquemment à la création d'analyseurs XML et à la définition de points d'entrée pour chaque événement XML.

Les données XML peuvent provenir soit d'une chaîne de caractères interne au script lui-même, soit d'un fichier externe.

$donnee = '<?xml version="1.0">'
                  '<element_racine>'
                  '<element_enfant>Valeur</element_enfant>'
                  ...
                  '</element_racine>';

Dans ce dernier cas, il faut ouvrir le fichier par l'intermédaire de la fonction fopen.

<?php
  $fichier = "fichier.xml";

  $id_fichier = fopen($fichier);
  $donnee_XML = fread($id_fichier, filesize($fichier));
?>

Les informations XML désormais disponibles à partir d'une variable peuvent être traitées par un analyseur XML préalablement créé par la fonction xml_parser_create.

$id_analyseur = xml_parser_create();

Suite à la création d'un analyseur XML, il devient possible de lancer l'analyse de données XML.

xml_parse($id_analyseur, $donnee_XML))

L'analyse d'un document XML peut s'effectuer par morceaux en accord avec la fonction fread. Le dernier argument devra alors indiquer par une valeur TRUE la fin de ce document.

$donnee_XML = fread($id_fichier, 4096));
xml_parse($id_analyseur, $donnee_XML, feof($id_fichier)));

L'analyse des informations XML provoque l'appel des gestionnaires d'événements adaptés à chaque fois qu'est rencontré un composant XML comme un élément, du texte ou encore une instruction de traitement.

Auparavant, il est nécessaire de notifier aux gestionnaires d'événement des fonctions destinées à exécuter des tâches précises.

function gestionnaire_debut($analyseur, 
                                   $nom_element, $tab_attributs)
{ # instructions... }

function gestionnaire_fin($analyseur, $nom_element)
{ # instructions... }

xml_set_element_handler($id_analyseur, 
                                   "gestionnaire_debut", "gestionnaire_fin");

Seul, le gestionnaire d'événement relatif aux éléments XML fait appel à deux fonctions. Ces fonctions se lancent respectivement lorsque l'analyseur rencontre une balise ouvrante ou une balise de fermeture.

<balise attribut="valeur">
      ==> entraine l'appel de la fonction gestionnaire_debut.
  Valeur textuelle
        ==> entraine l'appel de la fonction gestionnaire_texte.
</balise>
      ==> entraine l'appel de la fonction gestionnaire_fin.

La fonction dénommée gestionnaire_texte pourra être sollicitée si le gestionnaire d'événement xml_set_character_data_handler est lui-même appelé dans le script.

function gestionnaire_texte($analyseur, $nom_element)
{ # instructions... }

xml_set_character_data_handler($id_analyseur, 
                                   "gestionnaire_texte");

Il existe sept gestionnaires d'événements chargés d'activer des fonctions lorsque l'analyseur XML trouve des éléments, des données textuelles, des instructions de traitement, des entités non analysées, des références d'entités, des notations, etc..

La fonction gestionnaire_debut permet de récupérer d'une part le nom de l'élément rencontré pour les stocker dans une chaîne de caractères (second argument) et d'autre part le nom des attributs et leur valeur, lesquels sont placés dans un tableau associatif (troisième argument).

function gestionnaire_debut($id_analyseur, 
                                   $nom_element, $tab_attributs)
{
  echo $nom_element . "<br>";
  foreach($tab_attributs as $cle => $valeur)
  {
    echo "&nbsp;&nbsp;*&nbsp;" . $cle . " = " . $valeur . "<br>";
  }
}

Les données textuelles comprises au sein des éléments sont obtenues par le second argument de la fonction gestionnaire_texte.

function gestionnaire_texte($id_analyseur, $texte)
{
  echo $texte . "<br>";
}

Tous les caractères, y compris les espaces blancs tels que les tabulations et les retours de lignes, sont analysés et retournés dans l'argument $texte.

Les informations relatives aux erreurs XML peuvent être reueillies par l'intermédiaire de fonctions spéciales xml_get_error_code, xml_error_string, xml_get_current_line_number et xml_get_current_column_number retournant respectivement son numéro, son libellé et le numéro de la ligne et de la colonne où elle s'est produite dans le document XML.

sprintf("Erreur XML n°%d "
                    . "Message : %s "
                    . "Ligne  : %d "
                    . "Colonne : %d",
         xml_get_error_code($analyseur_xml),
         xml_error_string(xml_get_error_code($analyseur_xml)),
         xml_get_current_line_number($analyseur_xml),
         xml_get_current_column_number($analyseur_xml)
);

Enfin, la libération des ressources consommées par l'analyseur est réalisée par la fonction xml_parser_free.

xml_parser_free($id_analyseur);
Exemple [voir]
<?php
  function gestionnaire_debut($analyseur, $nom, $attribut)
  {
    global $nb;
    print "<b><u>Elément (niveau $nb) :</u></b> ";
    for ($i = 0; $i < $nb; $i++)
    {
      print "    ";
    }
    print "<b>" . $nom . "</b>";
    $nb++;
    if(sizeof($attribut))
    {
      foreach($attribut as $cle => $valeur)
      {
        echo ' (' . $cle . ' : ' . $valeur . ')<br>'; 
      }
    }
    else echo "<br>";
  }

  function gestionnaire_fin($analyseur, $nom)
  {
    global $nb;
    $nb--;
  }

  function gestionnaire_texte($analyseur, $texte)
  {
    global $nb;
    print "Texte (niveau $nb) :";
    for ($i = 0; $i < $nb; $i++)
    {
      print "      ";
    }
    print $texte . "<br>";
  }

  $fichier_xml = "recueil.xml";
  $nb = 0;

  $analyseur_xml = xml_parser_create();

  xml_set_element_handler($analyseur_xml, 
                 "gestionnaire_debut", "gestionnaire_fin");
  xml_set_character_data_handler($analyseur_xml, 
                                   "gestionnaire_texte");

  if (!($id_fichier = fopen($fichier_xml, "r")))
  {
    die("Impossible d'ouvrir le fichier XML !");
  }

  while ($donnee = fread($id_fichier, filesize($fichier_xml)))
  {
    if (!xml_parse($analyseur_xml, $donnee, feof($id_fichier)))
    {
      die(sprintf("Une erreur XML %s s'est produite "
                    . "à la ligne %d et à la colonne %d.",
                  xml_error_string(xml_get_error_code($analyseur_xml)),
                  xml_get_current_line_number($analyseur_xml),
                  xml_get_current_column_number($analyseur_xml)));
    }
  }
  xml_parser_free($analyseur_xml);
?>
Sommaire