如何将数组转换为PHP中的SimpleXML对象?
当前回答
下面是php 5.2代码,将数组的任何深度转换为xml文档:
Array
(
['total_stud']=> 500
[0] => Array
(
[student] => Array
(
[id] => 1
[name] => abc
[address] => Array
(
[city]=>Pune
[zip]=>411006
)
)
)
[1] => Array
(
[student] => Array
(
[id] => 2
[name] => xyz
[address] => Array
(
[city]=>Mumbai
[zip]=>400906
)
)
)
)
生成的XML如下所示:
<?xml version="1.0"?>
<student_info>
<total_stud>500</total_stud>
<student>
<id>1</id>
<name>abc</name>
<address>
<city>Pune</city>
<zip>411006</zip>
</address>
</student>
<student>
<id>1</id>
<name>abc</name>
<address>
<city>Mumbai</city>
<zip>400906</zip>
</address>
</student>
</student_info>
PHP代码片段
<?php
// function defination to convert array to xml
function array_to_xml( $data, &$xml_data ) {
foreach( $data as $key => $value ) {
if( is_array($value) ) {
if( is_numeric($key) ){
$key = 'item'.$key; //dealing with <0/>..<n/> issues
}
$subnode = $xml_data->addChild($key);
array_to_xml($value, $subnode);
} else {
$xml_data->addChild("$key",htmlspecialchars("$value"));
}
}
}
// initializing or creating array
$data = array('total_stud' => 500);
// creating object of SimpleXMLElement
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
// function call to convert array to xml
array_to_xml($data,$xml_data);
//saving generated xml file;
$result = $xml_data->asXML('/file/path/name.xml');
?>
本代码段中使用的SimpleXMLElement::asXML文档
其他回答
<?php function array_to_xml(array $arr, SimpleXMLElement $xml) { foreach ($arr as $k => $v) { is_array($v) ? array_to_xml($v, $xml->addChild($k)) : $xml->addChild($k, $v); } return $xml; } $test_array = array ( 'bla' => 'blub', 'foo' => 'bar', 'another_array' => array ( 'stack' => 'overflow', ), ); echo array_to_xml($test_array, new SimpleXMLElement('<root/>'))->asXML();
基于这里的所有其他内容,通过前缀@处理数值索引+属性,并可以将xml注入到现有节点:
Code
function simple_xmlify($arr, SimpleXMLElement $root = null, $el = 'x') {
// based on, among others http://stackoverflow.com/a/1397164/1037948
if(!isset($root) || null == $root) $root = new SimpleXMLElement('<' . $el . '/>');
if(is_array($arr)) {
foreach($arr as $k => $v) {
// special: attributes
if(is_string($k) && $k[0] == '@') $root->addAttribute(substr($k, 1),$v);
// normal: append
else simple_xmlify($v, $root->addChild(
// fix 'invalid xml name' by prefixing numeric keys
is_numeric($k) ? 'n' . $k : $k)
);
}
} else {
$root[0] = $arr;
}
return $root;
}//-- fn simple_xmlify
使用
// lazy declaration via "queryparam"
$args = 'hello=4&var[]=first&var[]=second&foo=1234&var[5]=fifth&var[sub][]=sub1&var[sub][]=sub2&var[sub][]=sub3&var[@name]=the-name&var[@attr2]=something-else&var[sub][@x]=4.356&var[sub][@y]=-9.2252';
$q = array();
parse_str($val, $q);
$xml = simple_xmlify($q); // dump $xml, or...
$result = get_formatted_xml($xml); // see below
结果
<?xml version="1.0"?>
<x>
<hello>4</hello>
<var name="the-name" attr2="something-else">
<n0>first</n0>
<n1>second</n1>
<n5>fifth</n5>
<sub x="4.356" y="-9.2252">
<n0>sub1</n0>
<n1>sub2</n1>
<n2>sub3</n2>
</sub>
</var>
<foo>1234</foo>
</x>
好处:格式化XML
function get_formatted_xml(SimpleXMLElement $xml, $domver = null, $preserveWhitespace = true, $formatOutput = true) {
// http://stackoverflow.com/questions/1191167/format-output-of-simplexml-asxml
// create new wrapper, so we can get formatting options
$dom = new DOMDocument($domver);
$dom->preserveWhiteSpace = $preserveWhitespace;
$dom->formatOutput = $formatOutput;
// now import the xml (converted to dom format)
/*
$ix = dom_import_simplexml($xml);
$ix = $dom->importNode($ix, true);
$dom->appendChild($ix);
*/
$dom->loadXML($xml->asXML());
// print
return $dom->saveXML();
}//-- fn get_formatted_xml
您可以直接在代码中使用以下函数,
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页面中。
我想要一个代码,将一个数组内的所有元素,并把它们作为属性,所有数组作为子元素。
对于像这样的东西
array (
'row1' => array ('head_element' =>array("prop1"=>"some value","prop2"=>array("empty"))),
"row2"=> array ("stack"=>"overflow","overflow"=>"overflow")
);
我会得到这样的结果
<?xml version="1.0" encoding="utf-8"?>
<someRoot>
<row1>
<head_element prop1="some value">
<prop2 0="empty"/>
</head_element>
</row1>
<row2 stack="overflow" overflow="stack"/>
</someRoot>
要实现这一点,代码如下,但要非常小心,它是递归的,实际上可能会导致stackoverflow:)
function addElements(&$xml,$array)
{
$params=array();
foreach($array as $k=>$v)
{
if(is_array($v))
addElements($xml->addChild($k), $v);
else $xml->addAttribute($k,$v);
}
}
function xml_encode($array)
{
if(!is_array($array))
trigger_error("Type missmatch xml_encode",E_USER_ERROR);
$xml=new SimpleXMLElement('<?xml version=\'1.0\' encoding=\'utf-8\'?><'.key($array).'/>');
addElements($xml,$array[key($array)]);
return $xml->asXML();
}
您可能希望添加数组长度检查,以便在数据部分中设置某些元素,而不是作为属性。
如果数组是关联的并且键是正确的,那么首先将它转换为xml可能会更容易。喜欢的东西:
function array2xml ($array_item) {
$xml = '';
foreach($array_item as $element => $value)
{
if (is_array($value))
{
$xml .= "<$element>".array2xml($value)."</$element>";
}
elseif($value == '')
{
$xml .= "<$element />";
}
else
{
$xml .= "<$element>".htmlentities($value)."</$element>";
}
}
return $xml;
}
$simple_xml = simplexml_load_string(array2xml($assoc_array));
另一种方法是首先创建基本的xml,例如
$simple_xml = simplexml_load_string("<array></array>");
然后对于数组的每个部分,使用类似于我的文本创建循环的东西,而不是使用simplexml函数“addChild”用于数组的每个节点。
稍后我将尝试使用这两个版本来更新这篇文章。