W3docs

xml_parse()

La fonction xml_parse() est une fonction PHP intégrée qui analyse des données XML selon le modèle SAX, de manière efficace et incrémentielle.

Qu'est-ce que xml_parse() ?

La fonction xml_parse() est une fonction PHP intégrée qui analyse des données XML. Elle appartient à l'extension XML Parser de PHP et implémente un parseur en flux de style SAX (Simple API for XML). Contrairement aux parseurs basés sur l'arbre, elle traite le XML de manière séquentielle, déclenchant des fonctions de rappel lorsqu'elle rencontre des éléments, des attributs et des données textuelles. Cela la rend très efficace pour analyser de grands fichiers XML sans charger l'ensemble du document en mémoire.

La fonction xml_parse() est utile lorsque vous devez analyser des données XML en PHP, par exemple pour extraire des données d'un fichier XML, transformer des données XML dans un autre format, ou traiter des flux XML en temps réel.

Syntaxe

La syntaxe de la fonction xml_parse() est la suivante :

xml_parse($parser, $data, $is_final = false): int

Paramètres

  • $parser — le handle du parseur XML retourné par xml_parser_create(). C'est l'objet qui conserve l'état de l'analyse.
  • $data — un fragment (ou la totalité) du texte XML à transmettre au parseur.
  • $is_final — à définir sur true lorsque vous passez le dernier fragment de données. Tant qu'il est false, le parseur conserve son état pour que vous puissiez rappeler xml_parse() avec le fragment suivant.

Valeur de retour

xml_parse() retourne 1 (valeur vraie) en cas de succès et 0 (valeur fausse) en cas d'échec. Elle ne retourne pas les données analysées — le contenu analysé est transmis aux callbacks de gestion que vous avez enregistrés. Lorsqu'elle retourne 0, examinez l'erreur avec xml_get_error_code() et xml_error_string().

Exemples d'utilisation

Voyons quelques exemples pratiques d'utilisation de xml_parse() en PHP.

Exemple 1 : Analyse XML avec des gestionnaires d'événements

xml_parse() est un parseur SAX : il ne construit pas de document pour vous, il déclenche des événements. Pour obtenir une sortie, vous devez enregistrer des fonctions de gestion. L'exemple ci-dessous utilise une chaîne XML inline pour fonctionner tel quel, sans fichier externe :

<?php
$xml = <<<XML
<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
</note>
XML;

$parser = xml_parser_create();
// Keep element names in their original case instead of upper-casing them.
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("Start: $name\n"),
    fn($p, $name)         => print("End:   $name\n")
);
xml_set_character_data_handler($parser, function ($p, $data) {
    $data = trim($data);
    if ($data !== "") {
        echo "Text:  $data\n";
    }
});

if (!xml_parse($parser, $xml, true)) {
    $code = xml_get_error_code($parser);
    echo "Error: " . xml_error_string($code)
       . " at line " . xml_get_current_line_number($parser);
}

xml_parser_free($parser);

Ce code affiche :

Start: note
Start: to
Text:  Tove
End:   to
Start: from
Text:  Jani
End:   from
End:   note

Le parseur parcourt le document de haut en bas et appelle vos gestionnaires d'élément de début, de données textuelles et d'élément de fin dans l'ordre du document. Nous les enregistrons avec xml_set_element_handler() et xml_set_character_data_handler(), passons tout en un seul appel ($is_final = true) et libérons le parseur avec xml_parser_free().

Exemple 2 : Analyse d'un fichier ou d'un flux de données par fragments

La véritable force de xml_parse() réside dans l'analyse incrémentielle : alimenter le document morceau par morceau pour qu'un fichier de plusieurs gigaoctets n'ait jamais besoin de tenir en mémoire. Passez $is_final = false pour chaque fragment sauf le dernier :

<?php
$parser = xml_parser_create();
xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("<$name>\n"),
    fn($p, $name)         => print("</$name>\n")
);

$handle = fopen("data.xml", "r");          // or php://stdin for a stream
while (($chunk = fread($handle, 4096)) !== false) {
    $isFinal = feof($handle);
    if (!xml_parse($parser, $chunk, $isFinal)) {
        $code = xml_get_error_code($parser);
        echo "XML error: " . xml_error_string($code)
           . " at line " . xml_get_current_line_number($parser);
        break;
    }
    if ($isFinal) {
        break;
    }
}
fclose($handle);
xml_parser_free($parser);

Comme le parseur conserve son état entre les appels, un élément peut commencer dans un fragment et se terminer dans un autre — xml_parse() assemble correctement les événements. C'est ce qui rend la fonction adaptée aux grands fichiers XML où une approche basée sur l'arbre comme SimpleXML épuiserait la mémoire.

Exemple 3 (référence) : analyse d'un fichier en une seule fois

Si votre XML est suffisamment petit pour tenir en mémoire, vous pouvez le lire avec file_get_contents() et passer la chaîne entière à xml_parse() en un seul appel. Les gestionnaires peuvent également être des fonctions nommées (noms en chaîne) plutôt que des closures :

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

// Define handler functions
function startElement($parser, $name, $attrs) {
    echo "Start element: $name\n";
}
function endElement($parser, $name) {
    echo "End element: $name\n";
}
function characterData($parser, $data) {
    echo "Data: $data\n";
}

// Set handlers
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

$xml_data = file_get_contents("data.xml");
if (!xml_parse($xml_parser, $xml_data, true)) {
    $error_message = xml_error_string(xml_get_error_code($xml_parser));
    $error_line = xml_get_current_line_number($xml_parser);
    echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);

Ce code crée un parseur XML avec xml_parser_create() et définit une option pour désactiver le repliage de casse. Il définit ensuite trois fonctions de rappel : startElement() pour les balises ouvrantes, endElement() pour les balises fermantes et characterData() pour le contenu textuel. Ces gestionnaires sont enregistrés avec xml_set_element_handler() et xml_set_character_data_handler().

Le script lit "data.xml" et le passe à xml_parse(). Au fur et à mesure que le parseur traite le XML en flux, il appelle automatiquement les gestionnaires enregistrés. Si une erreur survient lors de l'analyse, le code récupère le code et le message d'erreur avec xml_get_error_code() et xml_error_string(), et affiche une erreur descriptive. Enfin, il libère la mémoire du parseur avec xml_parser_free().

Pièges courants

  • Aucun gestionnaire, aucune sortie. xml_parse() ne déclenche que les callbacks que vous avez enregistrés. Sans gestionnaires définis, l'analyse réussit mais ne produit rien de visible.
  • Les données textuelles arrivent en morceaux. Un seul nœud texte peut déclencher xml_set_character_data_handler plusieurs fois (par exemple, autour de références d'entités), alors accumulez le texte dans un tampon plutôt que de supposer que vous le recevez en une seule fois.
  • Les espaces blancs comptent comme données textuelles. L'indentation entre les balises déclenche le gestionnaire de données textuelles. Utilisez trim() (comme dans l'Exemple 1) si vous ne vous intéressez qu'au texte réel.
  • Libérez toujours le parseur. Appelez xml_parser_free() lorsque vous avez terminé ; sous PHP 8+, le handle est un objet XMLParser récupéré par le ramasse-miettes, mais le libérer explicitement maintient la mémoire serrée dans les scripts à longue durée d'exécution.

Fonctions associées

Conclusion

La fonction xml_parse() de PHP est le moteur de l'extension XML Parser de style SAX. Au lieu de retourner un document, elle traite le XML en flux et déclenche les gestionnaires que vous enregistrez, retournant 1 en cas de succès et 0 en cas d'échec. Son paramètre $is_final vous permet d'analyser les données par fragments, ce qui explique pourquoi elle reste économe en mémoire même sur de très grands fichiers. Associez-la à xml_parser_create(), aux fonctions de configuration des gestionnaires et à xml_parser_free(), et vous disposez d'un moyen rapide et peu gourmand en mémoire pour traiter du XML en PHP.

Pratique

Pratique
Qu'est-ce que XML Parser en PHP ?
Qu'est-ce que XML Parser en PHP ?
Was this page helpful?