PHP数组甚至嵌套数据的XML转换 [英] php array to xml conversion even for nested data

查看:161
本文介绍了PHP数组甚至嵌套数据的XML转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有需要被转换为XML格式的阵列

  [名] => ABC
[邮件] => email@email.com
[手机] =>排列
                (
                 [手机] =>排列
                          (
                                [0] =>排列
                                    (
                                        [手机] => 91454599193
                                        [土地] => 9999999
                                    )                                [1] =>排列
                                    (
                                        [手机] => 54520199193
                                        [土地] => 9999999
                                    )                                [2] =>排列
                                    (
                                        [手机] => 90424249194
                                        [土地] => 5555555
                                    )                                [3] =>排列
                                    (
                                        [手机] => 44224199195
                                        [土地] => 8888888
                                    )                            )

我想这是在下面的格式

 <名称>&ABC LT; /名称>
&LT;电子邮件和GT; email@email.com< /电子邮件&GT;
 &LT;数码GT;
 &LT;电话&GT;
   &lt;便携式&GT; 545450199193&LT; /移动&GT;
   &LT;土地&GT; 9999999&LT; /土地&GT;
&LT; /电话&GT;
 &LT;电话&GT;
   &lt;便携式&GT; 575199193&LT; /移动&GT;
   &LT;土地&GT; 9999999&LT; /土地&GT;
&LT; /电话&GT;
&LT; /手机&GT;

请帮我....

这是我的职责,我已经写在我面临这个way.The问题是,具有数字指标必须显示XML节点的文本。例如: - 低于在电话阵列,有指数[0],[1]。我想要的[0],[1]要由&LT更换;手机&GT; 在我的XML页面。

 函数array_to_xml($值,和放大器; $ xml_student_info){
  的foreach($值$关键=&GT; $值){
    如果(is_array($值)){
        如果(!is_numeric($键)){
            $子节点= $ xml_student_info-&GT;的addChild($键);
            array_to_xml(价值$,$子节点);
        }
        其他{
            array_to_xml(价值$,$ xml_student_info);
         }
       }
        其他{
            $ xml_student_info-&GT;的addChild($键,$值);
        }
    }
}


解决方案

您可以通过使用递归解决您的问题。递归涉及罚款嵌套数据。

您通过创建增加值到父XML元素单一的功能做到这一点。

这功能再调用本身的情况下,发现嵌套数据。然后,它会先子元素添加到父,将调用本身与新元素添加为母。

如果要添加的数据只是一个字符串,它仍然会创建子,而是直接和树叶添加的字符串值。这是叶节点,在最外侧的

add函数,然后只需要读取你解析数据,并找出其中的四个案件要处理的:


  1. 只是一个字符串值,添加新元素(字符串命名元素)

  2. 添加有多个同名的新元素(0-N的命名元素索引阵列)

  3. 添加新的孩子,然后在那里添加N个新的儿童(键控阵列名为元素)

  4. 添加N个新儿童的父(键控阵列的编号(未命名)元素)

有关这个答案我认为这将是很好的一个匿名函数来试试这个。得到它递归的,它需要引用自身。然后,它可以在另一功能,将允许创建和进口商的里面裹着一个的SimpleXMLElement 允许轻松创建的XML。一旦包裹,甚至进一步将允许procude的XML字符串,但我一直认为外部做出明确的用法:

 要求('INC / simplexml_ pretty_print.php');$ XML =新的SimpleXMLElement('&LT;根/&GT;');
$进口商= $ createArrayImporter($ XML);
回声simplexml_ pretty_print($进口商($阵列));

在这个例子中 $阵列是从你的问题阵列。它包含这四种情况下,这是在这里进行处理,其中将被退回包裹内的另一个匿名函数调用 $ createArrayImporter()在 $添加功能在上面的例子

在进去,让我们回顾一下输入数组:

  $阵列= [
    '名'=&GT; 'ABC',
    电子邮件=&GT; email@email.com',
    '手机'=&GT;
    [
        '手机'= GT;
        [
            [
                移动= GT; '9000199193',
                土地= GT; '9999999',
            ]
            [
                移动= GT; '9000199193',
                土地= GT; '9999999',
            ]
            [
                移动= GT; '9000199194',
                土地= GT; '5555555',
            ]
            [
                移动= GT; '9000199195',
                土地= GT; '8888888',
            ]
        ]
    ]
];

和输出这造成:

 &LT;?XML版本=1.0&GT?;
&LT;根和GT;
  &LT;名称&gt;&ABC LT; /名称&gt;
  &LT;电子邮件和GT; email@email.com< /电子邮件&GT;
  &LT;数码GT;
    &LT;电话&GT;
      &lt;便携式&GT; 9000199193&LT; /移动&GT;
      &LT;土地&GT; 9999999&LT; /土地&GT;
    &LT; /电话&GT;
    &LT;电话&GT;
      &lt;便携式&GT; 9000199193&LT; /移动&GT;
      &LT;土地&GT; 9999999&LT; /土地&GT;
    &LT; /电话&GT;
    &LT;电话&GT;
      &lt;便携式&GT; 9000199194&LT; /移动&GT;
      &LT;土地&GT; 5555555&LT; /土地&GT;
    &LT; /电话&GT;
    &LT;电话&GT;
      &lt;便携式&GT; 9000199195&LT; /移动&GT;
      &LT;土地&GT; 8888888&LT; /土地&GT;
    &LT; /电话&GT;
  &LT; /手机&GT;
&LT; /根&GT;

和如何递归函数:

  $ =添加功能($的SimpleXMLElement主题,$键,$值)使用(安培; $补充)

主体是XML元素将数据添加到,关键是在阵列中的键和值同样可能或可能不被嵌套的值

因此​​,考虑最简单的情况下,你的键控(所有的数组索引都是字符串)数组应该被添加到根元素。

 案例$ isKeyed:
            的foreach($值$ oneof_key =&GT; $ oneof_value){
                $加($主题,$ oneof_key,$ oneof_value);
            }

这将通过沿着嵌套的值。例如首先在一个新的水平是 [名] =&GT; ABC ,所以键控字符串:

 情况下$ isString&放大器;&安培; $ hasKey:
            返回$标的&GT;的addChild($键,$值);

这只是增加了子元素与命名为关键的字符串值。

接下来的情况是

  [手机] =&GT;排列
     (
         [手机] =&GT;排列
             (
                 ...

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

 情况下$ isKeyed&放大器;&安培; $ hasKey:
            $主题= $标的&GT;的addChild($键);
            //落空意

它需要添加自己的键子元素堪比 $ isString和放大器;&安培; $ hasKey 的情况下,但随后需要处理它的数组值进一步上。这也是已收录的儿童(0-N作为索引)键控阵列,以便具有相同名称的多个元件可以被添加的巢式病例:

 案例$ isKeyed:
            的foreach($值$ oneof_key =&GT; $ oneof_value){
                $加($主题,$ oneof_key,$ oneof_value);
            }
            返回true;

这将告吹这种情况下,也创造一个没有钥匙,但只是编号键控阵列第四种情况。

这也是为什么我写的,他是三年半的情况下,这两个最后的在彼此之间共享某些部分。

包装这样的闭包内使这更容易,我将在一个小例子在这里只概述:

  $ createArrayImporter =功能($的SimpleXMLElement主题){    $ =添加功能($的SimpleXMLElement主题,$键,$值)使用(安培; $补充){         ...    };    返回功能(数组$阵列)使用($主题,$添加){        $加($主题,空,$阵列);
        返回$主题;
    };
};

因此​​,这可以踢东西了。你可以阅读完整的code矿的要点。

您发现了以下的答案,这也可以通过递归解决它面向一个类似的例子,但米矿对象:

数组的形式 - 即使它可能类似于 - 是你实际上是不同的。

和更多的指针有:

哪些不同类型的数组涉及到XML转换。

I have an array which needs to be converted to xml format.

[name] => ABC
[email] => email@email.com
[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 
                                    )

                            )
)

I want this to be in the following format

<name>ABC</name>
<email>email@email.com</email>
 <phones>
 <phone>
   <mobile>545450199193</mobile>
   <land>9999999</land>
</phone>
 <phone>
   <mobile>575199193</mobile>
   <land>9999999</land>
</phone>
</phones>

Please help me out....

This is my function, I have written in this way.The problem I am facing is that the index which have numbers must display text in the XML node. Ex:- Below at the phone array, there are index [0], [1]. I want the [0], [1] to be replaced by <phone> in my XML page..

  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");
        }
    }
}

解决方案

You can solve your issue by using recursion. Recursion deals fine with nested data.

You do this by creating a single function that is adding the value to a parent XML element.

That function then call itself in case it finds nested data. It then will add the child element to the parent first and will the call itself with the new element added as parent.

If the data to be added is just a string, it will still create the child, but add the string value directly and leaves. That are the leaf-nodes, at most outside.

The add function then only needs to read the data you parse in and find out which of the four cases are to be dealt with:

  1. Just add a new element with a string value (string for a named element)
  2. Add multiple new elements with the same name (0-n indexed array for a named element)
  3. Add a new children and then add N new children in there (keyed array for a named element)
  4. Add N new children to the parent (keyed array for a numbered (not named) element)

For this answer I thought it would be nice to try this with an anonymous function. To get it recursive, it needs to reference itself. It then can be wrapped inside another function that will allow to create and importer for a SimpleXMLElement which allows the easy creation of XML. Wrapped once further would even allow to procude the XML as string, however I keep that to the external to make the usage clear:

require('inc/simplexml_pretty_print.php');

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

In this example $array is the array from your question. It contains those four cases, which are processed here in the $add function which will be returned wrapped inside another anonymous function when called $createArrayImporter() in the example above.

Before going in, let's review the input array:

$array = [
    'name'   => 'ABC',
    'email'  => 'email@email.com',
    'phones' =>
    [
        'phone' =>
        [
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199193',
                'land'   => ' 9999999 ',
            ],
            [
                'mobile' => '9000199194',
                'land'   => ' 5555555 ',
            ],
            [
                'mobile' => '9000199195',
                'land'   => ' 8888888 ',
            ],
        ],
    ],
];

And the output this creates:

<?xml version="1.0"?>
<root>
  <name>ABC</name>
  <email>email@email.com</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>

And how to the recursive function:

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

The subject is the XML element to add data to, the key is the key in the array and the value likewise the value which may or may not to be nested.

So considering the most straight forward case, your keyed (all array indexes are strings) array should be added to the root element.

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

This will pass the values along as nested. For example first on the next level is [name] => ABC, so a keyed string:

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

This just adds the child element with the string value named as the key.

The next case is

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

That is a keyed array for a named element:

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

It needs to add it's own key as child element comparable to the $isString && $hasKey case, but then needs to process it's array value further on. Which is also the nested case of a keyed array that has indexed children (0-N as indexes), so that more than one element with the same name can be added:

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

It will fall through that case and also create the fourth case for the keyed array that has no key but is just numbered.

That's also why I wrote that his is three and a half cases, the two last ones are sharing some parts between each other.

Wrapping this inside a closure makes this more accessible, which I will only outline in a little example here:

$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;
    };
};

So this can kick things off. You can read the full code in a Gist of mine.

You find a similar example but m ore object oriented in the following answer, which also solves it via recursion:

The format of the array - even if it may look similar - is actually different to yours.

And for more pointers there is:

Which deals with different types of arrays to XML conversion.

这篇关于PHP数组甚至嵌套数据的XML转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆