如何将数组转换为PHP中的SimpleXML对象?
当前回答
一个简短的例子:
<?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中。
其他回答
整个XML结构定义在$data数组中:
function array2Xml($data, $xml = null)
{
if (is_null($xml)) {
$xml = simplexml_load_string('<' . key($data) . '/>');
$data = current($data);
$return = true;
}
if (is_array($data)) {
foreach ($data as $name => $value) {
array2Xml($value, is_numeric($name) ? $xml : $xml->addChild($name));
}
} else {
$xml->{0} = $data;
}
if (!empty($return)) {
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”用于数组的每个节点。
稍后我将尝试使用这两个版本来更新这篇文章。
我发现这个解与原来的问题相似
<?php
$test_array = array (
'bla' => 'blub',
'foo' => 'bar',
'another_array' => array (
'stack' => 'overflow',
),
);
class NoSimpleXMLElement extends SimpleXMLElement {
public function addChild($name,$value) {
parent::addChild($value,$name);
}
}
$xml = new NoSimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
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);
我发现所有的答案都是使用过多的代码。这里有一个简单的方法:
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();