PHP 里如何实现数组转 xml 并且格式化

2018-05-15 10:16:28 +08:00
 NEETLEE

如题,最近在琢磨 php 里把数组转换为 xml 格式的字符串并且支持格式化,昨天搞了一晚上,效果始终不理想。 今天来向各位大佬求助。 我这里贴一个我随便写的数组

$arr = [
  'arr1' => 'asdfasdfewrsdfwer',
  'arr2' => [
    'arr3' => [
      'asdfasdf' => 123213,
    ],
    'arr4' => '123123sdfsdf',
    'arr5' => [
      'arr6' => [
        'arr7' => [
          'arr8' => [
            '123123',
            'sadfsdf',
            'aserwer53453',
            'asdfwetrxcverwt',
          ],
        ],
      ],
    ],
  ],
];

再贴一下我写的存在问题的方法

/**


  $xml = '';
  foreach ($arr as $key => $value) {
    $xml .= "<$key>";
    if (is_array($value)) {
      $deep++;
      if ($format) {
        $xml .= PHP_EOL;
        $xml .= str_pad('', $deep * 2, ' ');
      }
      $xml .= arrayToXml($value, $format, $deep);
      $xml .= "</$key>";
    } else {
      $xml .= $value;
      $xml .= "</$key>";
    }
    if ($format) {
      $xml .= PHP_EOL;
      $next = next($arr);
      prev($arr);
      if ($next == false || is_array($next)) {
        $xml .= str_pad('', ($deep - 1) * 2, ' ');
      } else {
        $xml .= str_pad('', $deep * 2, ' ');
      }
      echo is_array($next) ? ' arr ' : $next;
      unset($next);
    }
    next($arr);
  }
  return $xml;
}
2559 次点击
所在节点    PHP
13 条回复
NEETLEE
2018-05-15 10:19:46 +08:00
/**
* 数组转换为 xml 格式的字符串
* @param array $arr 需要转换的数组
* @param boolean $format 是否格式化
* @return string xml 格式的字符串
*/
function arrayToXml($arr, $format = false, $deep = 0) {
$xml = '';
foreach ($arr as $key => $value) {
$xml .= "<$key>";
if (is_array($value)) {
$deep++;
if ($format) {
$xml .= PHP_EOL;
$xml .= str_pad('', $deep * 2, ' ');
}
$xml .= arrayToXml($value, $format, $deep);
$xml .= "</$key>";
} else {
$xml .= $value;
$xml .= "</$key>";
}
if ($format) {
$xml .= PHP_EOL;
$next = next($arr);
prev($arr);
if ($next == false || is_array($next)) {
$xml .= str_pad('', ($deep - 1) * 2, ' ');
} else {
$xml .= str_pad('', $deep * 2, ' ');
}
unset($next);
}
next($arr);
}
return $xml;
}


这是方法,不知道怎么的题目里方法名被干掉了...
KomeijiSatori
2018-05-15 10:22:20 +08:00
Chappako
2018-05-15 10:23:18 +08:00
littleylv
2018-05-15 10:26:09 +08:00
楼主如果出于研究学习的目的,挺好。
如果是为了解决实际问题,需要搞一晚上? Gayhub 搜一下,轮子一大堆。

请善用搜索!
InternetExplorer
2018-05-15 10:32:14 +08:00
有个叫 SimpleXMLElement 东西 了解一下 http://php.net/manual/en/simplexml.examples-basic.php#example-6636
imcnan
2018-05-15 10:35:43 +08:00
```php

public function arrayToXML($arr) {

$xml = "<xml>";
foreach ($arr as $key => $val) {
$node = "";
if ( is_string($val) || is_int($val) || is_double($val) || is_float($val) ) {
$val = htmlspecialchars($val);
$node = "<{$key}>{$val}</{$key}>";
} else if (is_array(val)) {
die("不应该有这个参数的");
}
$xml .= $node;
$xml .= "\n";
}
$xml .= "</xml>";
return $xml;
}

private function xmlToArray($xml) {

/*
<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2949f84b5ee561e9]]></appid>
<mch_id><![CDATA[1502705451]]></mch_id>
<nonce_str><![CDATA[YfEbfNE0xdUjJPAK]]></nonce_str>
<sign><![CDATA[5084033CADE92C9C32798406C3D5C82F]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx241217030922516345c975b91289464085]]></prepay_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
</xml>
*/
$ret = array();

$parser = xml_parser_create("UTF-8");
$values = array();
$keys = array();
xml_parse_into_struct($parser, $xml, $values, $keys);

foreach ($keys as $nodeName => $val) {
$id = $val[0];
if (!empty($values[$id]["value"])) {
$nodeName = strtoupper($nodeName);
$ret[$nodeName] = $values[$id]["value"];
}
}

return $ret;
}

```
msg7086
2018-05-15 10:43:12 +08:00
字符串手拼 XML ?
和我们用 grep+awk 解析 XML 的程序员有得一拼啊。

你要自己做 XML 转换,请从头写一个 XML 库。
NEETLEE
2018-05-15 11:02:27 +08:00
@littleylv
@msg7086
确实是拍脑门的想法,突然就想研究一下,反正下班了也没事,哈哈哈
NEETLEE
2018-05-15 12:35:34 +08:00
/**
* 将数组转成 xml
* @param array $arr 需要转换的数组
* @return string 转换的 xml
*/
function arrayConvertXml($arr, $xml = '', $deep = 1) {
if (!is_array($arr)) {
return null;
}
foreach ($arr as $key => $value) {
if (is_array($value)) {
if ($deep > 1) {
$xml .= str_pad('', ($deep - 1) * 2, ' ');
}
$xml .= "<$key>" . PHP_EOL;
$xml = arrayConvertXml($value, $xml, $deep + 1);
if ($deep > 1) {
$xml .= str_pad('', ($deep - 1) * 2, ' ');
}
$xml .= "</$key>" . PHP_EOL;
} else {
$xml .= str_pad('', ($deep - 1) * 2, ' ');
$xml .= "<$key>" . $value . "</$key>" . PHP_EOL;
}
}
return $xml;
}

和同事讨论了一下,最后得出如上函数,基本上没有问题了
msg7086
2018-05-15 12:59:45 +08:00
key 的转译没有,value 的转译也没有,随便来个特殊字符就崩了。
fuxkcsdn
2018-05-15 13:23:30 +08:00
NEETLEE
2018-05-15 13:36:09 +08:00
@msg7086 你是说<mch_id><![CDATA[1502705451]]></mch_id>这样的格式吗
msg7086
2018-05-15 14:36:44 +08:00
@NEETLEE 有很多转译方法……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/454894

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX