Vier Methoden zum Parsen von PHP-XML
XML-Verarbeitung wird häufig im Entwicklungsprozess angetroffen, und PHP bietet auch umfangreiche Unterstützung dafür. In diesem Artikel werden nur einige der Parsing-Technologien kurz beschrieben. einschließlich: XML-Parser, SimpleXML, XMLReader, DOMDocument.
1. XML-Expat-Parser:
XML-Parser verwendet den Expat-XML-Parser. Expat ist ein ereignisbasierter Parser, der XML-Dokumente als eine Reihe von Ereignissen behandelt. Wenn ein Ereignis auftritt, ruft es eine bestimmte Funktion auf, um es zu verarbeiten. Expat ist ein validierungsfreier Parser, der alle mit dem Dokument verknüpften DTDs ignoriert. Wenn das Dokument jedoch nicht in gutem Zustand ist, wird eine Fehlermeldung angezeigt. Da es ereignisbasiert ist und keine Validierung erfordert, ist Expat schnell und für Webanwendungen geeignet.
Der Vorteil des XML-Parsers ist seine gute Leistung, da er nicht das gesamte XML-Dokument in den Speicher lädt und dann verarbeitet, sondern es beim Parsen verarbeitet. Aber gerade aus diesem Grund ist es nicht für diejenigen geeignet, die die XML-Struktur dynamisch anpassen oder komplexe Operationen basierend auf der XML-Kontextstruktur ausführen müssen. Wenn Sie nur ein gut strukturiertes XML-Dokument analysieren und verarbeiten möchten, kann dies die Aufgabe gut erledigen. Es ist zu beachten, dass XML Parser nur drei Kodierungsformate unterstützt: US-ASCII, ISO-8859-1 und UTF-8. Wenn Ihre XML-Daten in anderen Kodierungen vorliegen, müssen Sie sie zuerst in eines der oben genannten drei konvertieren.
Im Allgemeinen gibt es zwei häufig verwendete Analysemethoden für XML-Parser (eigentlich zwei Funktionen): xml_parse_into_struct und xml_set_element_handler.
xml_parse_into_struct
Diese Methode analysiert die XML-Daten in zwei Arrays:
Index-Array – enthält einen Zeiger auf die Position des Werts im Werte-Array
Werte-Array – enthält Daten aus dem analysierten XML
Diese beiden Arrays sind in Textform etwas umständlich zu beschreiben, also schauen wir uns ein Beispiel an (aus der offiziellen PHP-Dokumentation)
$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);
Ausgabe :
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 ) )
Das Indexarray wird als Schlüssel bezeichnet, und der entsprechende Wert ist ein Array, das die Position aller Tags im Wertearray enthält. Suchen Sie dann an dieser Position den Wert, der dieser Beschriftung entspricht.
Wenn das Format jedes Datensatzes in XML unterschiedlich ist und nicht vollständig vereinheitlicht werden kann, sollten Sie beim Schreiben von Code darauf achten, dass Sie möglicherweise falsche Ergebnisse erhalten. Zum Beispiel das folgende Beispiel:
$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);
Wenn Sie auf die oben beschriebene Weise durchlaufen, scheint der Code einfach zu sein, aber es gibt versteckte Gefahren. Das Fatalste ist, das falsche Ergebnis zu erhalten (extra3 läuft zum zweiten Absatz innen). Wir müssen also strenger vorgehen:
$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; }
Tatsächlich verwende ich die Funktion xml_parse_into_struct selten. Wenn also der sogenannte „rigorose“ Code oben nicht beibehalten wird, treten Fehler auf andere Situationen. - -|
xml_set_element_handler
Mit dieser Methode wird die Rückruffunktion für den Parser festgelegt, um den Anfang und das Ende von Elementen zu verarbeiten. Ebenfalls enthalten ist die Rückruffunktion xml_set_character_data_handler, mit der Daten für den Parser festgelegt werden. Der so geschriebene Code ist klarer und einfacher zu warten.
Beispiel:
$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);
Es ist ersichtlich, dass die Set-Handler-Methode zwar viele Codezeilen enthält, aber klare Ideen und eine bessere Lesbarkeit aufweist, ihre Leistung jedoch etwas langsamer ist als die erste Methode und nicht sehr flexibel. XML Parser unterstützt PHP4 und ist für Systeme geeignet, die ältere Versionen verwenden. Geben Sie für eine PHP5-Umgebung der folgenden Methode Vorrang.
2. SimpleXML
SimpleXML ist eine Reihe einfacher und benutzerfreundlicher XML-Tools, die nach PHP5 bereitgestellt werden. Es kann XML in Objekte konvertieren, die für die Verarbeitung geeignet sind, und kann auch XML-Daten organisieren und generieren. Dies gilt jedoch nicht für XML, das Namespaces enthält, und das XML muss wohlgeformt sein. Es bietet drei Methoden: simplexml_import_dom, simplexml_load_file, simplexml_load_string. Der Funktionsname erklärt die Funktion intuitiv. Alle drei Funktionen geben SimpleXMLElement-Objekte zurück und Daten werden durch SimpleXMLElement-Operationen gelesen/hinzugefügt.
$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);
Der Vorteil von SimpleXML besteht darin, dass es einfach zu entwickeln ist. Der Nachteil besteht darin, dass das gesamte XML vor der Verarbeitung in den Speicher geladen wird, sodass ein XML-Dokument mit großem Inhalt möglicherweise nicht analysiert werden kann . Wenn Sie kleine Dateien lesen und die XML-Datei keinen Namespace enthält, ist SimpleXML eine gute Wahl.
3. XMLReader
XMLReader ist ebenfalls eine Erweiterung nach PHP5 (standardmäßig nach 5.1 installiert). Es bewegt sich im Dokumentenfluss wie ein Cursor und stoppt an jedem Knoten. Es ist sehr flexibel zu bedienen. Es bietet schnellen und nicht zwischengespeicherten Streaming-Zugriff auf Eingaben und kann einen Stream oder ein Dokument lesen, wodurch der Benutzer Daten daraus extrahieren und Datensätze überspringen kann, die für die Anwendung nicht von Bedeutung sind.
Ein Beispiel für die Verwendung der Google Weather API zum Abrufen von Informationen zeigt die Verwendung von XMLReader. Weitere Informationen finden Sie in der offiziellen Dokumentation.
$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 und XML-Parser sind ähnlich, sie arbeiten beide beim Lesen. Der große Unterschied besteht darin, dass das SAX-Modell ein „Push“-Modell ist, bei dem der Analysator jedes Mal Ereignisse an die Anwendung weiterleitet liest Die Anwendung wird benachrichtigt, wenn ein neuer Knoten abgerufen wird, und die Anwendung, die XmlReader verwendet, kann Knoten nach Belieben aus dem Reader extrahieren und ist besser kontrollierbar.
Da XMLReader auf libxml basiert, sollten Sie in der Dokumentation einiger Funktionen nachsehen, ob diese auf Ihre libxml-Version anwendbar sind.
4. DOMDocument
DOMDocument ist auch Teil der DOM-Erweiterung, die nach PHP5 eingeführt wurde. Es kann zum Erstellen oder Parsen von HTML/XML verwendet werden. Derzeit unterstützt es nur die UTF-8-Codierung.
$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中文网!