Le traitement XML dans PHP est une exigence commune, en particulier lors de l'accueil avec des interfaces tierces ou du traitement des fichiers de configuration. xml_parse () est une fonction sous-jacente fournie par PHP pour analyser les données XML. Cependant, lorsque vous traitez XML avec de nombreuses structures imbriquées ou des formats complexes, vous pouvez rencontrer des erreurs d'analyse si vous n'êtes pas prudent, ce qui entraîne une lecture correctement ou le programme se bloque directement.
Cet article expliquera comment éviter les erreurs d'analyse courantes lors de l'utilisation de xml_parse () pour gérer le XML imbriqué et fournir des exemples de code pratiques.
L'analyse XML de PHP utilise généralement le mode axé sur les événements et est utilisé avec les fonctions suivantes:
xml_parse ()
Voici un exemple d'analyse XML de base:
<?php
$xml = <<<XML
<books>
<book>
<title>PHP programmation</title>
<author>Zhang San</author>
</book>
<book>
<title>XML Combat réel</title>
<author>Li si</author>
</book>
</books>
XML;
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");
function startElement($parser, $name, $attrs) {
echo "Élément de démarrage: $name\n";
}
function endElement($parser, $name) {
echo "Élément final: $name\n";
}
function characterData($parser, $data) {
if (trim($data)) {
echo "Données de caractère: $data\n";
}
}
if (!xml_parse($parser, $xml, true)) {
die("XML erreur: " . xml_error_string(xml_get_error_code($parser)) .
" Dans le " . xml_get_current_line_number($parser) . " D'ACCORD");
}
xml_parser_free($parser);
?>
La fonction de rappel des caractères peut être déclenchée plusieurs fois lorsque les éléments sont imbriqués profondément, surtout s'il y a des ruptures de ligne ou des espaces entre les éléments. Le contenu doit être collecté à l'aide de variables de cache puis traités dans Endement () .
$depth = 0;
$currentTag = '';
$contentBuffer = [];
function startElement($parser, $name, $attrs) {
global $depth, $currentTag;
$depth++;
$currentTag = $name;
}
function endElement($parser, $name) {
global $depth, $currentTag, $contentBuffer;
if (isset($contentBuffer[$depth])) {
echo "élément $name La valeur de: " . trim($contentBuffer[$depth]) . "\n";
unset($contentBuffer[$depth]);
}
$depth--;
}
function characterData($parser, $data) {
global $depth, $contentBuffer;
if (!isset($contentBuffer[$depth])) {
$contentBuffer[$depth] = '';
}
$contentBuffer[$depth] .= $data;
}
Certains XML peuvent contenir des caractères illégaux, tels que des caractères de contrôle, des non-estimés et des symboles, etc. Pour le moment, le prétraitement est requis avant l'analyse:
$xml = preg_replace('/[^\x09\x0A\x0D\x20-\x7F]/u', '', $xml); // Supprimer les caractères illégaux
$xml = str_replace('&', '&', $xml); // S'échapper non codé &
Faites attention à ne pas vous échapper à plusieurs reprises pour vous assurer que les entités XML légitimes ne sont pas détruites.
Assurez-vous que les données XML sont encodées et spécifiées UTF-8 lors de la création de l'analyseur:
$parser = xml_parser_create('UTF-8');
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
Lorsque la structure XML imbriquée est complexe, il est recommandé d'utiliser une structure de pile pour enregistrer le niveau d'étiquette pour faciliter le traitement structuré ultérieur.
$elementStack = [];
function startElement($parser, $name, $attrs) {
global $elementStack;
array_push($elementStack, $name);
}
function endElement($parser, $name) {
global $elementStack;
array_pop($elementStack);
}
Grâce à la pile, vous pouvez obtenir le chemin ou la hiérarchie actuel en temps réel, et même créer un tableau multidimensionnel pour représenter la structure XML.
Pour les sources XML externes, assurez-vous d'ajouter un traitement d'exception pour empêcher la page de s'écraser en raison d'une défaillance d'analyse.
Utilisez libxml_use_internal_errors () avec simplexml_load_string () comme solution alternative à la défaillance du processus.
Si vous lisez XML à partir d'une interface comme https://api.m66.net/data.xml , veuillez d'abord utiliser File_get_contents () pour lire le contenu, puis le transmettre dans l'analyseur pour éviter les erreurs de réseau affectant le traitement logique.
$xmlContent = file_get_contents("https://api.m66.net/data.xml");
if ($xmlContent === false) {
die("Impossible de charger XML données");
}
Lorsque vous utilisez XML_Parse () pour traiter le XML imbriqué, les erreurs d'analyse courantes proviennent souvent de données de caractères incohérentes, de caractères illégaux, de codage irrégulier ou de logique d'analyse peu claire. Grâce à des spécifications de codage raisonnables, au prétraitement et à la conception structurée, vous pouvez considérablement améliorer la robustesse et la stabilité de l'analyse XML.
La maîtrise de la logique d'analyse sous-jacente peut également vous aider à traiter efficacement les structures de données XML lorsque vous n'êtes pas en mesure d'utiliser des bibliothèques XML avancées telles que SimplexML ou DomDocument.
Si vous devez simplifier davantage le processus d'analyse, vous pouvez envisager d'encapsuler une classe pour gérer la logique de l'analyseur et de la collecte de données, qui peut mieux réutiliser et maintenir le code.
Étiquettes associées:
xml_parse