如何将数组转换为PHP中的SimpleXML对象?
当前回答
您可以直接在代码中使用以下函数,
function artoxml($arr, $i=1,$flag=false){
$sp = "";
for($j=0;$j<=$i;$j++){
$sp.=" ";
}
foreach($arr as $key=>$val){
echo "$sp<".$key.">";
if($i==1) echo "\n";
if(is_array($val)){
if(!$flag){echo"\n";}
artoxml($val,$i+5);
echo "$sp</".$key.">\n";
}else{
echo "$val"."</".$key.">\n";
}
}
}
调用第一个参数作为数组的函数,第二个参数必须为1,这将增加完美缩进,第三个参数必须为真。
例如,如果要转换的数组变量是$array1,那么, 调用时,调用函数应该封装在<pre>标记中。
Artoxml($array 1,1,true);
请在执行文件后查看页面源代码,因为<和>符号将不会显示在html页面中。
其他回答
您可以使用我一直在研究的XMLParser。
$xml = XMLParser::encode(array(
'bla' => 'blub',
'foo' => 'bar',
'another_array' => array (
'stack' => 'overflow',
)
));
// @$xml instanceof SimpleXMLElement
echo $xml->asXML();
会导致:
<?xml version="1.0"?>
<root>
<bla>blub</bla>
<foo>bar</foo>
<another_array>
<stack>overflow</stack>
</another_array>
</root>
来自PHP 5.4
function array2xml($data, $root = null){
$xml = new SimpleXMLElement($root ? '<' . $root . '/>' : '<root/>');
array_walk_recursive($data, function($value, $key)use($xml){
$xml->addChild($key, $value);
});
return $xml->asXML();
}
我认为上面所有的解决方案都很好,但我看到目前为止,它并没有真正创建一个准确的格式良好的XML,因为数组键与$my_array[main_node][multiple_values][] = ARRAY ('id' => '1')然后转换为
<main_node>
<multiple_values>
<0>
<id>1 test</id>
</0>
</multiple_values>
<multiple_values>
<1>
<id>2 test</id>
</1>
</multiple_values>
</main_node>
这是XML解析器方面的一个问题……
I should be like this:
<main_node>
<multiple_values>
<id>1 test</id>
</multiple_values>
<multiple_values>
<id>2 test</id>
</multiple_values>
</main_node>
如果你用load_simple_xml来解析…你会得到完全相同的数组/对象结构。
我的函数还自动创建正确的根节点。
// Code to convert php array to xml document 20211112
function array2xml(array $data, $xml_class_obj = '', $group_by_parent_allowed = '', $options = array())
{
if(!$xml_class_obj) :
$is_root = 1;
$xml_class_obj = new XMLWriter();
$xml_class_obj->openMemory();
$xml_class_obj->setIndent(TRUE);
$xml_class_obj->setIndentString(' ');
if($options['encoding'] != '') $xml_class_obj->startDocument('1.0', $options['encoding']);
else $xml_class_obj->startDocument('1.0');
endif;
foreach ($data as $key => $value) {
if (is_array($value)) { // IS ARRAY
// check if allow below keys are int, if yes group them to same parent tree
$group_by_parent = $key;
foreach(array_keys($value) as $c_keys) :
if(!is_int($c_keys)) $group_by_parent = '';
endforeach;
if(empty($group_by_parent)) $xml_class_obj->startElement($key);
if($group_by_parent_allowed != '') $xml_class_obj->startElement($group_by_parent_allowed);
$this->array2xml($value, $xml_class_obj, $group_by_parent, $options);
if(empty($group_by_parent)) $xml_class_obj->endElement();
} else { // IS VALUE
if(is_string($value)) :
$xml_class_obj->startElement($key);
$xml_class_obj->writeCData($value);
$xml_class_obj->endElement();
else :
$xml_class_obj->writeElement($key, $value);
endif;
}
} // foreach
if($group_by_parent_allowed != '') $xml_class_obj->endElement();
if($is_root == 1) :
$xml_class_obj->endDocument();
return $xml_class_obj->outputMemory();
else :
return $xml_class_obj;
endif;
}
// usage
$ary_new_xml = array();
$ary_new_xml['order']['customer']['customerid'] = '123456';
$ary_new_xml['order']['customer']['customertype'] = 15;
$ary_new_xml['order']['orderprio'] = 2;
$ary_new_xml['order']['orderpos'][] = array('sku' => 9999910001111, 'quantity' => 3);
$ary_new_xml['order']['orderpos'][] = array('sku' => 9999910002222, 'quantity' => 1);
echo array2xml($ary_new_xml,'','',array('enconding' => 'UTF-8'));
结果:
<?xml version="1.0" encoding="UTF-8"?>
<order>
<customer>
<customerid>82936639</customerid>
<customertype>15</customertype>
</customer>
<orderprio>2</orderprio>
<orderpos>
<sku>9999910001111</sku>
<quantity>3</quantity>
</orderpos>
<orderpos>
<sku>9999910002222</sku>
<quantity>1</quantity>
</orderpos>
</order>
我希望这能帮助到一些人;)
我的答案,拼凑别人的答案。这应该可以纠正无法补偿数字键的错误:
function array_to_xml($array, $root, $element) {
$xml = new SimpleXMLElement("<{$root}/>");
foreach ($array as $value) {
$elem = $xml->addChild($element);
xml_recurse_child($elem, $value);
}
return $xml;
}
function xml_recurse_child(&$node, $child) {
foreach ($child as $key=>$value) {
if(is_array($value)) {
foreach ($value as $k => $v) {
if(is_numeric($k)){
xml_recurse_child($node, array($key => $v));
}
else {
$subnode = $node->addChild($key);
xml_recurse_child($subnode, $value);
}
}
}
else {
$node->addChild($key, $value);
}
}
}
array_to_xml()函数假定数组首先由数字键组成。如果数组有一个初始元素,则可以从array_to_xml()函数中删除foreach()和$elem语句,只传递$xml。
一个简短的例子:
<?php
$test_array = array (
'bla' => 'blub',
'foo' => 'bar',
'another_array' => array (
'stack' => 'overflow',
),
);
$xml = new SimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
print $xml->asXML();
结果
<?xml version="1.0"?>
<root>
<blub>bla</blub>
<bar>foo</bar>
<overflow>stack</overflow>
</root>
键和值会被交换——你可以在array_walk之前用array_flip()来修复这个问题。array_walk_recursive需要PHP 5。你可以用array_walk代替,但你不会得到'stack' => 'overflow'在XML中。