php 数组到 xml 的转换,即使是嵌套数据

2024-01-10

我有一个数组需要转换为 xml 格式。

[name] => ABC
[email] => [email protected] /cdn-cgi/l/email-protection
[phones] => Array
                (
                 [phone] => Array
                          (
                                [0] => Array
                                    (
                                        [mobile] => 91454599193
                                        [land] =>  9999999 
                                    )

                                [1] => Array
                                    (
                                        [mobile] => 54520199193
                                        [land] =>  9999999 
                                    )

                                [2] => Array
                                    (
                                        [mobile] => 90424249194
                                        [land] =>  5555555 
                                    )

                                [3] => Array
                                    (
                                        [mobile] => 44224199195
                                        [land] =>  8888888 
                                    )

                            )
)

我希望采用以下格式

<name>ABC</name>
<email>[email protected] /cdn-cgi/l/email-protection</email>
 <phones>
 <phone>
   <mobile>545450199193</mobile>
   <land>9999999</land>
</phone>
 <phone>
   <mobile>575199193</mobile>
   <land>9999999</land>
</phone>
</phones>

请帮帮我......

这是我的函数,我是这样写的。我面临的问题是包含数字的索引必须在 XML 节点中显示文本。例如:- 在电话数组下方,有索引 [0]、[1]。我希望将 [0], [1] 替换为<phone>在我的 XML 页面中..

  function array_to_xml($value, &$xml_student_info) {
  foreach($value as $key => $value) {
    if(is_array($value)) {
        if(!is_numeric($key)){
            $subnode = $xml_student_info->addChild("$key");
            array_to_xml($value, $subnode);
        }
        else{
            array_to_xml($value, $xml_student_info);
         }
       }
        else {
            $xml_student_info->addChild("$key","$value");
        }
    }
}

您可以使用递归来解决您的问题。递归可以很好地处理嵌套数据。

您可以通过创建一个将值添加到父 XML 元素的函数来实现此目的。

然后,该函数会调用自身,以防发现嵌套数据。然后,它首先将子元素添加到父元素,然后调用自身并将新元素添加为父元素。

如果要添加的数据只是一个字符串,它仍然会创建子级,但直接添加字符串值并离开。那是叶节点,最多在外面。

然后 add 函数只需要读取您解析的数据并找出要处理四种情况中的哪一种:

  1. 只需添加一个带有字符串值的新元素(命名元素的字符串)
  2. 添加多个具有相同名称的新元素(命名元素的 0-n 索引数组)
  3. 添加一个新的子元素,然后在其中添加 N 个新的子元素(命名元素的键控数组)
  4. 将 N 个新子级添加到父级(编号(未命名)元素的键控数组)

对于这个答案,我认为使用匿名函数尝试一下会很好。为了使其递归,它需要引用自身。然后可以将其包装在另一个函数中,该函数将允许创建和导入程序SimpleXMLElement它允许轻松创建 XML。进一步包装甚至允许将 XML 生成为字符串,但我将其保留给外部以使用法清晰:

require('inc/simplexml_pretty_print.php');

$xml      = new SimpleXMLElement('<root/>');
$importer = $createArrayImporter($xml);
echo simplexml_pretty_print($importer($array));

在这个例子中$array是你问题中的数组。它包含这四种情况,在此处进行处理$add调用时将返回包装在另一个匿名函数中的函数$createArrayImporter()在上面的例子中。

在进入之前,我们先回顾一下输入数组:

$array = [
    'name'   => 'ABC',
    'email'  => '[email protected] /cdn-cgi/l/email-protection',
    'phones' =>
    [
        'phone' =>
        [
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199194',
                'land'   => ' 5555555 ',
            ],
            [
                'mobile' => '9000199195',
                'land'   => ' 8888888 ',
            ],
        ],
    ],
];

这创建的输出:

<?xml version="1.0"?>
<root>
  <name>ABC</name>
  <email>[email protected] /cdn-cgi/l/email-protection</email>
  <phones>
    <phone>
      <mobile>9000199193</mobile>
      <land> 9999999 </land>
    </phone>
    <phone>
      <mobile>9000199193</mobile>
      <land> 9999999 </land>
    </phone>
    <phone>
      <mobile>9000199194</mobile>
      <land> 5555555 </land>
    </phone>
    <phone>
      <mobile>9000199195</mobile>
      <land> 8888888 </land>
    </phone>
  </phones>
</root>

以及如何递归函数:

$add = function (SimpleXMLElement $subject, $key, $value) use (&$add)

主题是要添加数据的 XML 元素,键是数组中的键,值同样可以嵌套也可以不嵌套。

因此,考虑到最直接的情况,您的键控(所有数组索引都是字符串)数组应该添加到根元素。

        case $isKeyed:
            foreach ($value as $oneof_key => $oneof_value) {
                $add($subject, $oneof_key, $oneof_value);
            }

这会将值作为嵌套传递。例如,下一个级别的第一个是[name] => ABC,所以一个键控字符串:

        case $isString && $hasKey:
            return $subject->addChild($key, $value);

这只是添加具有名为键的字符串值的子元素。

下一个案例是

[phones] => Array
     (
         [phone] => Array
             (
                 ...

这是一个命名元素的键控数组:

        case $isKeyed && $hasKey:
            $subject = $subject->addChild($key);
            // fall-through intended

它需要添加它自己的键作为与$isString && $hasKey情况,但随后需要进一步处理它的数组值。这也是具有索引子项(0-N 作为索引)的键控数组的嵌套情况,因此可以添加多个同名元素:

        case $isKeyed:
            foreach ($value as $oneof_key => $oneof_value) {
                $add($subject, $oneof_key, $oneof_value);
            }
            return true;

它将经历这种情况,并为没有键但只是编号的键控数组创建第四种情况。

这也是为什么我写道他的案件是三个半案件,最后两个案件彼此共享一些部分。

将其包装在闭包内可以使其更易于访问,我将仅在此处的一个小示例中概述:

$createArrayImporter = function (SimpleXMLElement $subject) {

    $add = function (SimpleXMLElement $subject, $key, $value) use (&$add) {

         ...

    };

    return function (Array $array) use ($subject, $add) {

        $add($subject, null, $array);
        return $subject;
    };
};

所以这可以开始事情。您可以阅读完整的代码我的要点 https://gist.github.com/4445046.

您在下面的答案中找到了一个类似的示例,但更多的是面向对象的,它也通过递归解决了这个问题:

  • php:导出数组到xml的麻烦 https://stackoverflow.com/a/13219372/367456

数组的格式 - 即使它可能看起来相似 - 实际上与您的不同。

对于更多指针,有:

  • 如何将数组转换为 SimpleXML https://stackoverflow.com/q/1397036/367456

其中处理不同类型的数组到 XML 的转换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php 数组到 xml 的转换,即使是嵌套数据 的相关文章

随机推荐