Quatre méthodes d'analyse XML de PHP
Le traitement XML est souvent rencontré dans le processus de développement, et PHP dispose également d'un support riche pour cela. Cet article ne décrit que brièvement certaines des technologies d'analyse Description, notamment : analyseur XML, SimpleXML, XMLReader, DOMDocument.
1. XML Expat Parser :
XML Parser utilise l'analyseur XML Expat. Expat est un analyseur basé sur des événements qui traite les documents XML comme une série d'événements. Lorsqu'un événement se produit, il appelle une fonction spécifiée pour le gérer. Expat est un analyseur sans validation qui ignore toute DTD liée au document. Cependant, si le document n’est pas en bon état, il se retrouvera avec un message d’erreur. Parce qu'il est basé sur des événements et n'a aucune validation, Expat est rapide et adapté aux applications Web.
L'avantage de XML Parser est ses bonnes performances, car il ne charge pas l'intégralité du document XML en mémoire puis le traite, mais le traite tout en l'analysant. Mais c'est précisément pour cette raison qu'il ne convient pas à ceux qui ont besoin d'ajuster dynamiquement la structure XML ou d'effectuer des opérations complexes basées sur la structure du contexte XML. Si vous souhaitez simplement analyser et traiter un document XML bien structuré, il peut alors bien accomplir la tâche. Il convient de noter que XML Parser ne prend en charge que trois formats d'encodage : US-ASCII, ISO-8859-1 et UTF-8. Si vos données XML sont dans d'autres encodages, vous devez d'abord les convertir dans l'un des trois ci-dessus.
Il existe généralement deux méthodes d'analyse couramment utilisées pour XML Parser (en fait deux fonctions) : xml_parse_into_struct et xml_set_element_handler.
xml_parse_into_struct
Cette méthode analyse les données XML en deux tableaux :
tableau d'index - contient un pointeur vers l'emplacement de la valeur dans le tableau Value
tableau de valeurs - contient des données du XML analysé
Ces deux tableaux sont un peu difficiles à décrire textuellement, regardons donc un exemple (tiré de la documentation officielle php)
$simple = "<para><note>simple note</note></para>"; $p = xml_parser_create(); xml_parse_into_struct($p, $simple, $vals, $index); xml_parser_free($p); echo "Index array\n"; print_r($index); echo "\nVals array\n"; print_r($vals);
Sortie :
Index array Array ( [PARA] => Array ( [0] => 0 [1] => 2 ) [NOTE] => Array ( [0] => 1 ) ) Vals array Array ( [0] => Array ( [tag] => PARA [type] => open [level] => 1 ) [1] => Array ( [tag] => NOTE [type] => complete [level] => 2 [value] => simple note ) [2] => Array ( [tag] => PARA [type] => close [level] => 1 ) )
Le tableau d'index est nommé comme clé, et la valeur correspondante est un tableau, qui inclut la position de toutes ces balises dans le tableau de valeurs. Puis via cette position, trouvez la valeur correspondant à ce label.
Si le format de chaque ensemble de données en XML est différent et ne peut pas être complètement unifié, alors vous devez faire attention lors de l'écriture du code, vous risquez d'obtenir des résultats erronés. Par exemple, l'exemple suivant :
$xml = ' <infos> <para><note>note1</note><extra>extra1</extra></para> <para><note>note2</note></para> <para><note>note3</note><extra>extra3</extra></para> </infos> '; $p = xml_parser_create(); xml_parse_into_struct($p, $xml, $values, $tags); xml_parser_free($p); $result = array();
//下面的遍历方式有bug隐患 for ($i=0; $i<3; $i++) { $result[$i] = array(); $result[$i]["note"] = $values[$tags["NOTE"][$i]]["value"]; $result[$i]["extra"] = $values[$tags["EXTRA"][$i]]["value"]; } print_r($result);
Si vous parcourez de la manière ci-dessus, le code semble simple, mais il y a des dangers cachés. Le plus fatal est d'obtenir un mauvais résultat (extra3. court jusqu'au deuxième para à l'intérieur). Il faut donc parcourir de manière plus rigoureuse :
$result = array(); $paraTagIndexes = $tags['PARA']; $paraCount = count($paraTagIndexes); for($i = 0; $i < $paraCount; $i += 2) { $para = array(); //遍历para标签对之间的所有值 for($j = $paraTagIndexes[$i]; $j < $paraTagIndexes[$i+1]; $j++) { $value = $values[$j]['value']; if(empty($value)) continue; $tagname = strtolower($values[$j]['tag']); if(in_array($tagname, array('note','extra'))) { $para[$tagname] = $value; } } $result[] = $para; }
En fait, j'utilise rarement la fonction xml_parse_into_struct, donc si le code dit "rigoureux" ci-dessus n'est pas conservé, il y aura des bugs dans d'autres situations. - -|
xml_set_element_handler
Cette méthode consiste à définir la fonction de rappel pour que l'analyseur gère le début et la fin des éléments. La fonction de rappel xml_set_character_data_handler est également incluse pour définir les données de l'analyseur. Le code écrit de cette manière est plus clair et plus facile à maintenir.
Exemple :
$xml = <<<XML <infos> <para><note>note1</note><extra>extra1</extra></para> <para><note>note2</note></para> <para><note>note3</note><extra>extra3</extra></para> </infos> XML; $result = array(); $index = -1; $currData; function charactor($parser, $data) { global $currData; $currData = $data; } function startElement($parser, $name, $attribs) { global $result, $index; $name = strtolower($name); if($name == 'para') { $index++; $result[$index] = array(); } } function endElement($parser, $name) { global $result, $index, $currData; $name = strtolower($name); if($name == 'note' || $name == 'extra') { $result[$index][$name] = $currData; } } $xml_parser = xml_parser_create(); xml_set_character_data_handler($xml_parser, "charactor"); xml_set_element_handler($xml_parser, "startElement", "endElement"); if (!xml_parse($xml_parser, $xml)) { echo "Error when parse xml: "; echo xml_error_string(xml_get_error_code($xml_parser)); } xml_parser_free($xml_parser); print_r($result);
On peut voir que bien que la méthode du gestionnaire set comporte de nombreuses lignes de code, elle a des idées claires et une meilleure lisibilité, mais ses performances sont légèrement plus lentes que la première méthode, et pas très flexible. XML Parser prend en charge PHP4 et convient aux systèmes utilisant des versions plus anciennes. Pour l'environnement PHP5, privilégiez la méthode suivante.
2. SimpleXML
SimpleXML est un ensemble d'outils XML simples et faciles à utiliser fournis après PHP5. Il peut convertir du XML en objets faciles à traiter, et peut également organiser et générer des données XML. Cependant, cela ne s'applique pas aux espaces de noms contenant du XML et le XML doit être bien formé. Il fournit trois méthodes : simplexml_import_dom, simplexml_load_file, simplexml_load_string. Le nom de la fonction explique intuitivement la fonction. Les trois fonctions renvoient des objets SimpleXMLElement et les données sont lues/ajoutées via des opérations SimpleXMLElement.
$string = <<<XML <?xml version='1.0'?> <document> <cmd>login</cmd> <login>imdonkey</login> </document> XML; $xml = simplexml_load_string($string); print_r($xml); $login = $xml->login;//这里返回的依然是个SimpleXMLElement对象 print_r($login); $login = (string) $xml->login;//在做数据比较时,注意要先强制转换 print_r($login);
L'avantage de SimpleXML est qu'il est simple à développer. L'inconvénient est qu'il charge l'intégralité du XML dans la mémoire avant le traitement, il peut donc ne pas être en mesure d'analyser un document XML avec beaucoup de choses. de contenu. Si vous lisez de petits fichiers et que le XML ne contient pas d'espace de noms, alors SimpleXML est un bon choix.
3. XMLReader
XMLReader est également une extension après PHP5 (installée par défaut après 5.1). Elle se déplace dans le flux du document comme un curseur et s'arrête à chaque nœud. Il fournit un accès en continu rapide et sans mise en cache aux entrées et peut lire un flux ou un document, permettant à l'utilisateur d'en extraire des données et d'ignorer les enregistrements qui n'ont pas de sens pour l'application.
Un exemple d'utilisation de l'API Google Weather pour obtenir des informations montre l'utilisation de XMLReader. Seul un petit nombre de fonctions sont impliquées ici. Pour plus d'informations, veuillez vous référer à la documentation officielle.
$xml_uri = 'http://www.google.com/ig/api?weather=Beijing&hl=zh-cn'; $current = array(); $forecast = array(); $reader = new XMLReader(); $reader->open($xml_uri, 'gbk'); while ($reader->read()) { //get current data if ($reader->name == "current_conditions" && $reader->nodeType == XMLReader::ELEMENT) { while($reader->read() && $reader->name != "current_conditions") { $name = $reader->name; $value = $reader->getAttribute('data'); $current[$name] = $value; } } //get forecast data if ($reader->name == "forecast_conditions" && $reader->nodeType == XMLReader::ELEMENT) { $sub_forecast = array(); while($reader->read() && $reader->name != "forecast_conditions") { $name = $reader->name; $value = $reader->getAttribute('data'); $sub_forecast[$name] = $value; } $forecast[] = $sub_forecast; } } $reader->close();
XMLReader et XML Parser sont similaires, ils fonctionnent tous les deux en lecture. La grande différence est que le modèle SAX est un modèle "push", dans lequel l'analyseur envoie des événements à l'application, à chaque fois. reads L'application est avertie lorsqu'un nouveau nœud est récupéré et l'application utilisant XmlReader peut extraire les nœuds du lecteur à volonté, avec une meilleure contrôlabilité.
Étant donné que XMLReader est basé sur libxml, vous devez vous référer à la documentation de certaines fonctions pour voir si elles sont applicables à votre version de libxml.
4. DOMDocument
DOMDocument fait également partie de l'extension DOM lancée après PHP5. Il peut être utilisé pour créer ou analyser du HTML/xml. Actuellement, il ne prend en charge que l'encodage utf-8.
$xmlstring = <<<XML <?xml version='1.0'?> <document> <cmd attr='default'>login</cmd> <login>imdonkey</login> </document> XML; $dom = new DOMDocument(); $dom->loadXML($xmlstring); print_r(getArray($dom->documentElement)); function getArray($node) { $array = false; if ($node->hasAttributes()) { foreach ($node->attributes as $attr) { $array[$attr->nodeName] = $attr->nodeValue; } } if ($node->hasChildNodes()) { if ($node->childNodes->length == 1) { $array[$node->firstChild->nodeName] = getArray($node->firstChild); } else { foreach ($node->childNodes as $childNode) { if ($childNode->nodeType != XML_TEXT_NODE) { $array[$childNode->nodeName][] = getArray($childNode); } } } } else { return $node->nodeValue; } return $array; }
从函数名上看感觉跟JavaScript很像,应该是借鉴了一些吧。DOMDocument也是一次性将xml载入内存,所以内存问题同样需要注意。PHP提供了这么多的xml处理方式,开发人员在选择上就要花些时间了解,选择适合项目需求及系统环境、又便于维护的方法。
感谢阅读,希望能帮助到大家,谢谢大家对本站支持!
更多php 解析xml 的四种方法详细介绍相关文章请关注PHP中文网!