如何将数组转换为PHP中的SimpleXML对象?
当前回答
下面讨论名称空间。在本例中,构造包装器以包含名称空间定义,并将其传递给函数。使用冒号来标识命名空间。
测试数组
$inarray = [];
$inarray['p:apple'] = "red";
$inarray['p:pear'] = "green";
$inarray['p:peach'] = "orange";
$inarray['p1:grocers'] = ['p1:local' => "cheap", 'p1:imported' => "expensive"];
$xml = new SimpleXMLElement( '<p:wrapper xmlns:p="http://namespace.org/api" xmlns:p1="http://namespace.org/api2 /> ');
array_to_xml($xml,$inarray);
function array_to_xml(SimpleXMLElement $object, array $data)
{
$nslist = $object->getDocNamespaces();
foreach ($data as $key => $value)
{
$nspace = null;
$keyparts = explode(":",$key,2);
if ( count($keyparts)==2)
$nspace = $nslist[$keyparts[0]];
if (is_array($value))
{
$key = is_numeric($key) ? "item$key" : $key;
$new_object = $object->addChild($key,null,$nspace);
array_to_xml($new_object, $value);
}
else
{
$key = is_numeric($key) ? "item$key" : $key;
$object->addChild($key, $value,$nspace);
}
}
}
其他回答
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);
如果数组是关联的并且键是正确的,那么首先将它转换为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”用于数组的每个节点。
稍后我将尝试使用这两个版本来更新这篇文章。
只是对上面的函数进行了编辑,当键是数字时,添加前缀“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 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 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();