【问题标题】:Convert a PHP data structure into serialised XML将 PHP 数据结构转换为序列化的 XML
【发布时间】:2016-05-15 13:12:32
【问题描述】:

我有以下数组。我什至不确定该数组的格式是否正确。我什至不确定我的阵列是否正确。

我想使用 PHP 将以下数组转换为序列化的 XML。我正在为属性使用 attr 标记。

这是数组:

$data = Array(
'name' => 'account',
'attr' => Array(
    'id' => 123456
),
'children' => Array(
    Array(
        'name' => 'name',
        'attr' => Array(),
        'children' => Array(
            'BBC'
        ),
    ),
    Array(
        'name' => 'monitors',
            'attr' => Array(),
        'children' => Array(
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235632
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/'
                        )
                    )
                )
            ),
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235633
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/news'
                        )
                    )
                )
            )
        )
    )
)
);

【问题讨论】:

  • 这个问题不太清楚——你只是问数组是否有效,或者如何进行xml转换?在检查数组是否有效方面 - 我只是尝试 var_dump($data) 并在定义它之后检查你在第一个实例中获得的输出。运行 php -l 将显示是否存在解析错误,但对定位它没有帮助。附言您发布的数组对象是有效的 php
  • 请问如何进行xml转换
  • 如果它是一个简单的数组,有很多代码可用。但是我的数组到处都是,我不知道如何管理它。

标签: php xml xml-serialization


【解决方案1】:

使用递归函数很容易。您的基本数组包含 3 个元素,名称、属性列表和子元素。因此,您的函数必须创建并附加一个具有名称的节点,设置所有属性并迭代子数据。如果孩子是一个标量它是一个文本节点,对于一个数组调用函数本身。

function appendTo($parent, $data) {
  $document = $parent->ownerDocument ?: $parent; 
  $node = $parent->appendChild($document->createElement($data['name']));
  if (isset($data['attr']) && is_array($data['attr'])) {
    foreach ($data['attr'] as $name => $value) {
      $node->setAttribute($name, $value);
    }
  }  
  if (isset($data['children']) && is_array($data['children'])) {
    foreach ($data['children'] as $name => $childData) {
      if (is_scalar($childData)) {
        $node->appendChild($document->createTextNode($childData));
      } elseif (is_array($childData)) {
        appendTo($node, $childData);
      }
    }
  }
}

$document = new DOMDocument();
$document->formatOutput = TRUE;
appendTo($document, $data);

echo $document->saveXml();

输出:

<?xml version="1.0"?>
<account id="123456">
  <name>BBC</name>
  <monitors>
    <monitor id="5235632">
      <url>http://www.bbc.co.uk/</url>
    </monitor>
    <monitor id="5235633">
      <url>http://www.bbc.co.uk/news</url>
    </monitor>
  </monitors>
</account>

【讨论】:

    【解决方案2】:

    试试下面的功能

    function assocArrayToXML($root_element_name,$ar)
    {
        $xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
        $f = function($f,$c,$a) {
                foreach($a as $k=>$v) {
                    if(is_array($v)) {
                        $ch=$c->addChild($k);
                        $f($f,$ch,$v);
                    } else {
                        $c->addChild($k,$v);
                    }
                }
        };
        $f($f,$xml,$ar);
        return $xml->asXML();
    } 
    
    
    echo assocArrayToXML("root",$data);
    

    test it here

    【讨论】:

    • 不要使用create_function(),它是一个隐藏的eval()。使用anonymous function
    • @ThW 你能删除否决票吗,这可能只是作为评论提出的
    • 您方法的输出仍然是损坏的 XML。您有数字标签名称。 btw 尝试使用带有&amp; 的网址。
    • 是的,我知道@ThW 你是对的,它不会以 OP 最终想要的方式生成 xml。将数组转换为 xml 是一个相当快速的功能。我可能会编辑或添加替代解决方案。
    【解决方案3】:

    希望这会有所帮助。

    <?php
    function array2xml($arr)
    {
        $dom = new DomDocument('1.0');
        /*
        *Create Root
        */  
        $root = $dom->createElement($arr['name']);
        if(isset($arr['attr']) && !empty($arr['attr']))
        {
            foreach($arr['attr'] as $key=>$val)
            $root->setAttribute($key, $val); 
        }
        $root = $dom->appendChild($root);
        createChilds($arr['children'], $dom, $root);
    
        header('Content-type: text/xml');
        echo $dom->saveXML(); 
    }
    function createChilds($arr, $dom, $parent)
    {
        foreach($arr as $child)
        {
            if(isset($child['name']))
                $node = $dom->createElement($child['name']);
            /*
            *Add Attributes
            */
            if(isset($child['attr']) && !empty($child['attr']))
            {
                foreach($child['attr'] as $key=>$val)
                $node->setAttribute($key, $val); 
            }
            /*
            *Add Childs Recursively
            */      
            if(isset($child['children']) && is_array($child['children']))
            {
                createChilds($child['children'], $dom, $node);
            }
            else if(isset($child) && is_string($child))
            {
                $text = $dom->createTextNode($child); 
                $parent->appendChild($text); 
            }
            if(isset($node))
            $parent->appendChild($node);
        }
    }
    
    $data = Array(
    'name' => 'account',
    'attr' => Array(
        'id' => 123456
    ),
    'children' => Array(
        Array(
            'name' => 'name',
            'attr' => Array(),
            'children' => Array(
                'BBC'
            ),
        ),
        Array(
            'name' => 'monitors',
                'attr' => Array(),
            'children' => Array(
                Array(
                    'name' => 'monitor',
                    'attr' => Array(
                        'id' => 5235632
                    ),
                    'children' => Array(
                        Array(
                            'name' => 'url',
                            'attr' => Array(),
                            'children' => Array(
                                'http://www.bbc.co.uk/'
                            )
                        )
                    )
                ),
                Array(
                    'name' => 'monitor',
                    'attr' => Array(
                        'id' => 5235633
                    ),
                    'children' => Array(
                        Array(
                            'name' => 'url',
                            'attr' => Array(),
                            'children' => Array(
                                'http://www.bbc.co.uk/news'
                            )
                        )
                    )
                )
            )
        )
    )
    );
    array2xml($data);
    ?>
    

    【讨论】:

    • 解释在哪里?请添加一些点或 cmets 以使您的代码不言自明。
    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 2017-01-04
    • 2014-10-13
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    相关资源
    最近更新 更多