如何将数组转换为PHP中的SimpleXML对象?
当前回答
我发现所有的答案都是使用过多的代码。这里有一个简单的方法:
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();
其他回答
来自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();
}
下面讨论名称空间。在本例中,构造包装器以包含名称空间定义,并将其传递给函数。使用冒号来标识命名空间。
测试数组
$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);
}
}
}
这里有一个函数帮我解决了这个问题:
就像这样叫它
echo arrayToXml("response",$arrayIWantToConvert);
function arrayToXml($thisNodeName,$input){
if(is_numeric($thisNodeName))
throw new Exception("cannot parse into xml. remainder :".print_r($input,true));
if(!(is_array($input) || is_object($input))){
return "<$thisNodeName>$input</$thisNodeName>";
}
else{
$newNode="<$thisNodeName>";
foreach($input as $key=>$value){
if(is_numeric($key))
$key=substr($thisNodeName,0,strlen($thisNodeName)-1);
$newNode.=arrayToXml3($key,$value);
}
$newNode.="</$thisNodeName>";
return $newNode;
}
}
总之……我使用了onokazu的代码(谢谢!),并添加了在XML中重复标记的能力,它还支持属性,希望有人发现它有用!
<?php
function array_to_xml(array $arr, SimpleXMLElement $xml) {
foreach ($arr as $k => $v) {
$attrArr = array();
$kArray = explode(' ',$k);
$tag = array_shift($kArray);
if (count($kArray) > 0) {
foreach($kArray as $attrValue) {
$attrArr[] = explode('=',$attrValue);
}
}
if (is_array($v)) {
if (is_numeric($k)) {
array_to_xml($v, $xml);
} else {
$child = $xml->addChild($tag);
if (isset($attrArr)) {
foreach($attrArr as $attrArrV) {
$child->addAttribute($attrArrV[0],$attrArrV[1]);
}
}
array_to_xml($v, $child);
}
} else {
$child = $xml->addChild($tag, $v);
if (isset($attrArr)) {
foreach($attrArr as $attrArrV) {
$child->addAttribute($attrArrV[0],$attrArrV[1]);
}
}
}
}
return $xml;
}
$test_array = array (
'bla' => 'blub',
'foo' => 'bar',
'another_array' => array (
array('stack' => 'overflow'),
array('stack' => 'overflow'),
array('stack' => 'overflow'),
),
'foo attribute1=value1 attribute2=value2' => 'bar',
);
$xml = array_to_xml($test_array, new SimpleXMLElement('<root/>'))->asXML();
echo "$xml\n";
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xml);
$dom->formatOutput = TRUE;
echo $dom->saveXml();
?>
其他解决方案:
$marray=array(....);
$options = array(
"encoding" => "UTF-8",
"output_type" => "xml",
"version" => "simple",
"escaping" => array("non-ascii, on-print, markup")
);
$xmlres = xmlrpc_encode_request('root', $marray, $options);
print($xmlres);