Although many service providers now provide JSON interfaces for us to use, there are still many services that must use XML as the interface format, which requires us to process data in XML format. Perform parsing conversion. There are no functions like json_encode() and json_decode() in PHP that allow us to easily convert, so when operating XML data, everyone often needs to write their own code to achieve it.
Today, we introduce the use of some object methods in the SPL extension library to handle XML data format conversion. First, we define a class, which is equivalent to encapsulating a class that operates XML data conversion for our future use. If you just want to test the effect, you can also write the following function directly.
class ConvertXml{ // .... }
Convert XML to PHP array
class ConvertXml{ public function xmlToArray(SimpleXMLIterator $xml): array { $res = []; for ($xml->rewind(); $xml->valid(); $xml->next()) { $a = []; if (!array_key_exists($xml->key(), $a)) { $a[$xml->key()] = []; } if ($xml->hasChildren()) { $a[$xml->key()][] = $this->xmlToArray($xml->current()); } else { $a[$xml->key()] = (array) $xml->current()->attributes(); $a[$xml->key()]['value'] = strval($xml->current()); } $res[] = $a; } return $res; } // ..... } $wsdl = 'http://flash.weather.com.cn/wmaps/xml/china.xml'; $xml = new SimpleXMLIterator($wsdl, 0, true); $convert = new ConvertXml(); // var_dump($convert->xmlToArray($xml)); // array(37) { // [0]=> // array(1) { // ["city"]=> // array(2) { // ["@attributes"]=> // array(9) { // ["quName"]=> // string(9) "黑龙江" // ["pyName"]=> // string(12) "heilongjiang" // ["cityname"]=> // string(9) "哈尔滨" // ["state1"]=> // string(1) "7" // ["state2"]=> // string(1) "3" // ["stateDetailed"]=> // string(15) "小雨转阵雨" // ["tem1"]=> // string(2) "21" // ["tem2"]=> // string(2) "16" // ["windState"]=> // string(21) "南风6-7级转4-5级" // } // ["value"]=> // string(0) "" // } // } // [1]=> // array(1) { // ["city"]=> // array(2) {
Here, we are using the SimpleXMLIterator object. As can be seen from the name, its role is to generate SimpleXMLElement objects that can be traversed. The first parameter is properly formatted XML text or a link address. The second parameter is some option parameters. Here we can just give 0 directly. The third parameter indicates whether the first parameter is a link address, here we give true .
We generated the SimpleXMLIterator object on the client side and passed it to the xmlToArray() method. In this way, the SimpleXMLIterator object allows us to traverse each node. The next thing is very simple. We only need to determine whether the node has child nodes. If there are child nodes, call the current method recursively. If there are no child nodes, get the node's attributes and content.
This test link is to obtain weather information. Each node in the returned content has only attributes and no content. This is reflected in the converted array where the value field is empty.
PHP array or object converted to XML
class ConvertXml{ // ...... const UNKNOWN_KEY = 'unknow'; public function arrayToXml(array $a) { $xml = new SimpleXMLElement('<?xml version="1.0" standalone="yes"?><root></root>'); $this->phpToXml($a, $xml); return $xml->asXML(); } protected function phpToXml($value, &$xml) { $node = $value; if (is_object($node)) { $node = get_object_vars($node); } if (is_array($node)) { foreach ($node as $k => $v) { if (is_numeric($k)) { $k = 'number' . $k; } if (!is_array($v) && !is_object($v)) { $xml->addChild($k, $v); } else { $newNode = $xml->addChild($k); $this->phpToXml($v, $newNode); } } } else { $xml->addChild(self::UNKNOWN_KEY, $node); } } } var_dump($convert->arrayToXml($data)); // string(84454) "<?xml version="1.0" standalone="yes"?> // <root><unlikely-outliner><subject><mongo-db><outline><chapter><getting-started><number0> ........... // "
In arrayToXml(), we first created a basic root node structure using the SimpleXMLElement object. Then use the phpToXml() method to create all nodes. Why split it into two methods? Because the phpToXml() method needs to be called recursively, we do not need to re-create the root node during each recursion. We only need to use addChild() under the root node to add child nodes.
In the code of phpToXml(), we also use the get_object_vars() function. That is, when the content of the array item passed in is an object, all properties of the object can be obtained through this function. If you think of an object as an array, each attribute value is its key-value pair.
When traversing each key value, we determine whether the content corresponding to the current key is an array or an object. If the content is not in these two forms, the current content will be directly added as a child node of the current node. If it is an array or object, continue to add recursively until all the array contents are traversed.
The $data content of the test is very long. You can check it directly on Github through the link to the test code.
Summary
The content of this article is to simply learn the use of two objects for XML operations in an SPL extension library. Through them, we can easily convert XML data format. Of course, we have other methods for XML format conversion, which we will learn about later!
Test code:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/Use the object method in the SPL library in PHP Conversion of XML and array.php