W3docs

xml_set_character_data_handler()

La fonction xml_set_character_data_handler() définit un callback utilisateur comme gestionnaire de données de caractères dans un analyseur XML PHP.

La fonction xml_set_character_data_handler() enregistre un callback défini par l'utilisateur que l'analyseur XML appelle chaque fois qu'il rencontre des données de caractères — le contenu textuel situé entre les balises XML. Elle appartient à l'extension xml héritée, qui encapsule l'analyseur Expat orienté événements, et fait donc partie de l'API d'analyse en flux ("style SAX") de PHP plutôt que des approches arborescentes DOMDocument ou SimpleXML.

On utilise cette fonction lorsqu'on souhaite capturer ou transformer le texte à l'intérieur des éléments au fur et à mesure que le document est parcouru — par exemple, pour collecter le titre de chaque <item> dans un flux RSS, ou pour effectuer une transformation sur du texte extrait sans jamais construire l'intégralité du document en mémoire. Elle est presque toujours utilisée conjointement avec xml_set_element_handler(), qui indique à quel élément appartient le texte.

Attention : L'extension xml est héritée. Pour tout nouveau code, préférez SimpleXML ou DOMDocument. Utilisez ce gestionnaire lorsque vous maintenez des analyseurs Expat existants ou avez réellement besoin d'un traitement en flux pour des documents très volumineux.

Syntaxe

xml_set_character_data_handler(XMLParser $parser, callable $handler): bool
  • $parser — l'analyseur créé par xml_parser_create().
  • $handler — le callback à invoquer pour les données de caractères. Passez un nom de fonction sous forme de chaîne, une closure, ou un tableau pour un callback de méthode. Passer une chaîne vide "" supprime un gestionnaire précédemment enregistré.

La fonction retourne true en cas de succès.

La signature du gestionnaire

Votre gestionnaire reçoit deux arguments — l'analyseur et le fragment de texte :

function handler(XMLParser $parser, string $data): void

D'anciennes documentations indiquent parfois un troisième paramètre $length, mais l'extension xml basée sur Expat n'en passe pas. Sur PHP 8+, déclarer un troisième paramètre obligatoire génère une ArgumentCountError, donc gardez votre gestionnaire à deux paramètres (ou rendez les paramètres supplémentaires optionnels).

Exemples d'utilisation

Exemple 1 : Un gestionnaire de données de caractères minimal

Créez un analyseur, attachez un gestionnaire, puis alimentez-le avec une chaîne XML. Le gestionnaire affiche simplement le texte reçu après suppression des espaces :

function handle_character_data($parser, $data) {
    echo trim($data);
}

$xml_parser = xml_parser_create();
xml_set_character_data_handler($xml_parser, "handle_character_data");

$xml_data = '<root><item>Hello World</item></root>';
xml_parse($xml_parser, $xml_data, true);

xml_parser_free($xml_parser);
// Output: Hello World

xml_parser_create() construit l'analyseur, xml_set_character_data_handler() connecte le callback, xml_parse() traite les données en flux (le true final indique qu'il s'agit du dernier fragment), et xml_parser_free() libère l'analyseur.

Le piège du découpage en fragments

L'analyseur peut appeler votre gestionnaire plusieurs fois pour un seul élément, et il se déclenche aussi pour les espaces entre les éléments. Il ne vous fournit pas une chaîne propre par élément. Voici ce qui se passe avec deux éléments et quelques indentations :

function show($parser, $data) {
    echo '[' . $data . "]\n";
}

$p = xml_parser_create();
xml_set_character_data_handler($p, "show");

$xml = '<root><item>Hello World</item>  <item>Goodbye</item></root>';
xml_parse($p, $xml, true);
xml_parser_free($p);

// Output:
// [Hello World]
// [  ]
// [Goodbye]

L'espace de deux caractères entre le </item> et le <item> suivant déclenche son propre appel. Un texte long peut également arriver découpé en plusieurs appels. Pour cette raison, vous devez mettre en tampon les données et n'agir qu'une fois que vous savez que l'élément est terminé.

Exemple 2 : Mise en tampon du texte avec un gestionnaire d'éléments

Le modèle fiable consiste à : réinitialiser un tampon au démarrage d'un élément, y ajouter chaque fragment de données de caractères, et lire le tampon à la fin de l'élément. C'est pourquoi xml_set_element_handler() est presque toujours associé à cette fonction.

$buffer = '';

function start_element($parser, $name, $attrs) {
    global $buffer;
    $buffer = '';            // start collecting fresh text
}

function character_data($parser, $data) {
    global $buffer;
    $buffer .= $data;        // chunks may arrive in pieces — append
}

function end_element($parser, $name) {
    global $buffer;
    $text = trim($buffer);
    if ($text !== '') {
        echo "$name: $text\n";
    }
}

$parser = xml_parser_create();
xml_set_element_handler($parser, "start_element", "end_element");
xml_set_character_data_handler($parser, "character_data");

$xml = '<books><title>PHP Basics</title><title>Advanced XML</title></books>';
xml_parse($parser, $xml, true);
xml_parser_free($parser);

// Output:
// TITLE: PHP Basics
// TITLE: Advanced XML

Les noms d'éléments arrivent en majuscules par défaut car l'analyseur normalise la casse. Pour conserver la casse d'origine, désactivez la normalisation avec xml_parser_set_option() :

xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

Pièges courants

  • Supposer un seul appel par élément. Comme illustré ci-dessus, les données de caractères peuvent être livrées en plusieurs fragments ; accumulez-les toujours dans un tampon.
  • Appels avec uniquement des espaces. Les indentations et les sauts de ligne entre les balises déclenchent le gestionnaire avec des espaces. Filtrez-les avec trim() avant d'agir.
  • Un troisième paramètre de gestionnaire. Le gestionnaire Expat ne passe que $parser et $data ; un paramètre $length obligatoire provoque une ArgumentCountError.
  • Enregistrement du gestionnaire après l'analyse. Attachez tous les gestionnaires avant d'appeler xml_parse(), sinon les événements seront déjà passés.

Conclusion

xml_set_character_data_handler() enregistre un callback pour le texte entre les balises XML dans l'extension xml héritée de PHP, basée sur Expat. Son gestionnaire prend deux arguments — l'analyseur et le fragment de données — et peut se déclencher plusieurs fois par élément, y compris pour les espaces. L'approche fiable consiste donc à mettre le texte en tampon et à le traiter à la fin de l'élément via xml_set_element_handler(). Pour les nouveaux projets, préférez les API modernes SimpleXML ou DOMDocument ; utilisez cette fonction pour maintenir des analyseurs existants ou traiter en flux des documents très volumineux.

Pratique

Pratique
Que fait la fonction 'xml_set_character_data_handler()' en PHP ?
Que fait la fonction 'xml_set_character_data_handler()' en PHP ?
Was this page helpful?