如何将数组转换为PHP中的SimpleXML对象?
当前回答
我想要一个代码,将一个数组内的所有元素,并把它们作为属性,所有数组作为子元素。
对于像这样的东西
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();
}
您可能希望添加数组长度检查,以便在数据部分中设置某些元素,而不是作为属性。
其他回答
下面是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文档
这是我的入口,简单而干净。
function array2xml($array, $xml = false){
if($xml === false){
$xml = new SimpleXMLElement('<root/>');
}
foreach($array as $key => $value){
if(is_array($value)){
array2xml($value, $xml->addChild($key));
}else{
$xml->addChild($key, $value);
}
}
return $xml->asXML();
}
header('Content-type: text/xml');
print array2xml($array);
只是对上面的函数进行了编辑,当键是数字时,添加前缀“key_”
// initializing or creating array
$student_info = array(your array data);
// creating object of SimpleXMLElement
$xml_student_info = new SimpleXMLElement("<?xml version=\"1.0\"?><student_info></student_info>");
// function call to convert array to xml
array_to_xml($student,$xml_student_info);
//saving generated xml file
$xml_student_info->asXML('file path and name');
function array_to_xml($student_info, &$xml_student_info) {
foreach($student_info as $key => $value) {
if(is_array($value)) {
if(!is_numeric($key)){
$subnode = $xml_student_info->addChild("$key");
array_to_xml($value, $subnode);
}
else{
$subnode = $xml_student_info->addChild("key_$key");
array_to_xml($value, $subnode);
}
}
else {
if(!is_numeric($key)){
$xml_student_info->addChild("$key","$value");
}else{
$xml_student_info->addChild("key_$key","$value");
}
}
}
}
我发现所有的答案都是使用过多的代码。这里有一个简单的方法:
function to_xml(SimpleXMLElement $object, array $data)
{
foreach ($data as $key => $value) {
if (is_array($value)) {
$new_object = $object->addChild($key);
to_xml($new_object, $value);
} else {
// if the key is an integer, it needs text with it to actually work.
if ($key != 0 && $key == (int) $key) {
$key = "key_$key";
}
$object->addChild($key, $value);
}
}
}
然后,将数组发送到使用递归的函数中就很简单了,因此它将处理多维数组:
$xml = new SimpleXMLElement('<rootTag/>');
to_xml($xml, $my_array);
现在$xml包含了一个漂亮的xml对象,它完全基于您编写数组的方式。
print $xml->asXML();
function array2xml(array $data, SimpleXMLElement $object = null, $oldNodeName = 'item')
{
if (is_null($object)) $object = new SimpleXMLElement('<root/>');
$isNumbered = true;
$idx = 0;
foreach ($data as $key => $x)
if (is_string($key) || ($idx++ != $key + 0))
$isNumbered = false;
foreach ($data as $key => $value)
{
$attribute = preg_match('/^[0-9]/', $key . '') ? $key : null;
$key = (is_string($key) && !preg_match('/^[0-9]/', $key . '')) ? $key : preg_replace('/s$/', '', $oldNodeName);
if (is_array($value))
{
$new_object = $object->addChild($key);
if (!$isNumbered && !is_null($attribute)) $new_object->addAttribute('id', $attribute);
array2xml($value, $new_object, $key);
}
else
{
if (is_bool($value)) $value = $value ? 'true' : 'false';
$node = $object->addChild($key, htmlspecialchars($value));
if (!$isNumbered && !is_null($attribute) && !isset($node->attributes()->id))
$node->addAttribute('id', $attribute);
}
}
return $object;
}
例如,该函数返回一个<obj>…</obj><obj>…</obj>数值索引的XML标记。
输入:
array(
'people' => array(
'dog',
'cat',
'life' => array(
'gum',
'shoe',
),
'fish',
),
array('yeah'),
)
输出:
<root>
<people>
<people>dog</people>
<people>cat</people>
<life>
<life>gum</life>
<life>shoe</life>
</life>
<people>fish</people>
<people>
<people>yeah</people>
</people>
</people>
</root>
这应该能满足所有的共同需求。也许你可以把第三行改成:
$key = is_string($key) ? $key : $oldNodeName . '_' . $key;
或者如果你正在处理以s结尾的复数:
$key = is_string($key) ? $key : preg_replace('/s$/', '', $oldNodeName);