在PHP和XML之间转换

当考虑PHP本地数据类型和XML之间的转换时,我们通常会将数组作为主要目标。考虑到这一点,从PHP数组到XML的转换过程与反过来的转换过程截然不同。

{% hint style=”info” %} 对象也可以考虑转换;但是,在XML中很难呈现对象方法。不过,可以通过使用get_object_vars()函数来表示属性,该函数将对象属性读入一个数组。 {% endhint %}

如何做…

1.首先,我们定义一个Application\Parse\ConvertXml类。这个类将持有将XML转换为PHP数组的方法,反之亦然。我们将需要SPL中的SimpleXMLElementSimpleXMLIterator类。

  1. namespace Application\Parse;
  2. use SimpleXMLIterator;
  3. use SimpleXMLElement;
  4. class ConvertXml
  5. {
  6. }
  1. 接下来,我们定义一个xmlToArray()方法,它将接受一个SimpleXMLIterator实例作为参数。它将被递归调用,并从一个XML文档中产生一个PHP数组。我们利用SimpleXMLIterator的能力在XML文档中前进,使用key()current()next()rewind()方法来导航。
  1. public function xmlToArray(SimpleXMLIterator $xml) : array
  2. {
  3. $a = array();
  4. for( $xml->rewind(); $xml->valid(); $xml->next() ) {
  5. if(!array_key_exists($xml->key(), $a)) {
  6. $a[$xml->key()] = array();
  7. }
  8. if($xml->hasChildren()){
  9. $a[$xml->key()][] = $this->xmlToArray($xml->current());
  10. }
  11. else{
  12. $a[$xml->key()] = (array) $xml->current()->attributes();
  13. $a[$xml->key()]['value'] = strval($xml->current());
  14. }
  15. }
  16. return $a;
  17. }
  1. 对于反向过程,也叫递归,我们定义了两个方法。第一个方法arrayToXml(),设置一个初始SimpleXMLElement实例,然后调用第二个方法`phpToXml()。
  1. public function arrayToXml(array $a)
  2. {
  3. $xml = new SimpleXMLElement(
  4. '<?xml version="1.0" standalone="yes"?><root></root>');
  5. $this->phpToXml($a, $xml);
  6. return $xml->asXML();
  7. }
  1. 请注意,在第二个方法中,我们使用get_object_vars()来处理数组元素中的一个对象。你还会注意到,单独的数字是不允许作为XML标签的,这意味着要在数字前面添加一些文本。
  1. protected function phpToXml($value, &$xml)
  2. {
  3. $node = $value;
  4. if (is_object($node)) {
  5. $node = get_object_vars($node);
  6. }
  7. if (is_array($node)) {
  8. foreach ($node as $k => $v) {
  9. if (is_numeric($k)) {
  10. $k = 'number' . $k;
  11. }
  12. if (is_array($v)) {
  13. $newNode = $xml->addChild($k);
  14. $this->phpToXml($v, $newNode);
  15. } elseif (is_object($v)) {
  16. $newNode = $xml->addChild($k);
  17. $this->phpToXml($v, $newNode);
  18. } else {
  19. $xml->addChild($k, $v);
  20. }
  21. }
  22. } else {
  23. $xml->addChild(self::UNKNOWN_KEY, $node);
  24. }
  25. }

如何运行…

作为 XML 文档的示例,你可以使用美国国家气象局的 Web 服务定义语言(WSDL)。这是一个描述 SOAP 服务的 XML 文档,可以在 http://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl 找到。

我们将使用SimpleXMLIterator类来提供一个迭代机制,然后你可以配置自动加载,并得到一个ApplicationParseConvertXml的实例。使用xmlToArray()将WSDL转换为PHP数组。

  1. require __DIR__ . '/../Application/Autoload/Loader.php';
  2. Application\Autoload\Loader::init(__DIR__ . '/..');
  3. use Application\Parse\ConvertXml;
  4. $wsdl = 'http://graphical.weather.gov/xml/'
  5. . 'SOAP_server/ndfdXMLserver.php?wsdl';
  6. $xml = new SimpleXMLIterator($wsdl, 0, TRUE);
  7. $convert = new ConvertXml();
  8. var_dump($convert->xmlToArray($xml));

由此产生的数组如图所示。

在PHP和XML之间转换 - 图1

要做相反的事情,使用本配方中描述的arrayToXml()方法。作为源文件,你可以使用source/data/mongo.db.global.php文件,该文件包含了一个通过O’Reilly Media提供的MongoDB培训视频的大纲(免责声明:由本作者提供!)。使用相同的自动加载器配置和Application\Parse\ConvertXml实例,这里是你可以使用的示例代码。

  1. $convert = new ConvertXml();
  2. header('Content-Type: text/xml');
  3. echo $convert->arrayToXml(include CONFIG_FILE);

这是在浏览器中的输出。

在PHP和XML之间转换 - 图2