关于php:在PHP中使用SPL库中的对象方法进行XML与数组的转换

4次阅读

共计 3100 个字符,预计需要花费 8 分钟才能阅读完成。

虽说当初很多的服务提供商都会提供 JSON 接口供咱们应用,然而,还是有不少的服务仍然必须应用 XML 作为接口格局,这就须要咱们来对 XML 格局的数据进行解析转换。而 PHP 中并没有像 json_encode()、json_decode() 这样的函数可能让咱们不便地进行转换,所以在操作 XML 数据时,大家往往都须要本人写代码来实现。

明天,咱们介绍的是应用 SPL 扩大库中的一些对象办法来解决 XML 数据格式的转换。首先,咱们定义一个类,就相当于封装一个操作 XML 数据转换的类,不便咱们未来应用。如果只是测试成果的话,间接写上面的函数也是能够的。

class ConvertXml{// ....}

XML 转换为 PHP 数组

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) {

在这里,咱们应用的是 SimpleXMLIterator 对象。从名称中就能够看出,它的作用是生成能够遍历的 SimpleXMLElement 对象。第一个参数是格局正确的 XML 文本或者链接地址。第二个参数是一些选项参数,这里咱们间接给 0 就能够了。第三个参数则是指明第一个参数是否是链接地址,这里咱们给 true。

咱们在客户端生成了 SimpleXMLIterator 对象,并传递到 xmlToArray() 办法中。这样 SimpleXMLIterator 对象就能让咱们遍历各个结点了,接下来的事件就很简略了,咱们只须要判断一下结点是否还有子结点,如果有子结点则递归调用以后这个办法。如果没有子结点了,就获取结点的属性和内容。

这个测试链接是获取天气信息的,返回的内容中每个结点都只有属性没有内容,体现在转换后的数组中就是 value 字段都是空的。

PHP 数组或对象转换为 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>  ...........
// "

咱们在 arrayToXml() 中,先应用 SimpleXMLElement 对象创立了一个根本的根结点构造。而后应用 phpToXml() 办法来创立所有结点。为什么要拆成两个办法呢?因为 phpToXml() 办法是须要递归调用的,在每次递归的时候咱们不须要从新的去创立根结点,只须要在根结点上面应用 addChild() 增加子结点就能够了。

在 phpToXml() 的代码中,咱们还应用了 get_object_vars() 函数。就是当传递进来的数组项内容是对象时,通过这个函数能够获取对象的所有属性。如果将对象看做是一个数组的话,每个属性值就是它的键值对。

在对每个键值遍历时,咱们判断以后的键对应的内容是否是数组或者是对象。如果不是这两种模式的内容的话,就间接将以后的内容增加为以后结点的子结点。如果是数组或对象的话,就持续递归地增加直到数组内容全副遍历实现。

测试的 $data 内容十分长,大家能够间接通过测试代码的链接去 Github 上查阅。

总结

这篇文章的内容是简略的学习了一个 SPL 扩大库中对于 XML 操作的两个对象的应用。通过它们,咱们能够不便的转换 XML 数据格式。当然,对于 XML 的格局转换来说,咱们还有其它的办法,当前学到了再说!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/ 在 PHP 中应用 SPL 库中的对象办法进行 XML 与数组的转换.php

参考文档:

《PHP7 编程实战》

各自媒体平台均可搜寻【硬核项目经理】

正文完
 0