如何将数组转换为PHP中的SimpleXML对象?
当前回答
您可以直接在代码中使用以下函数,
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页面中。
其他回答
如果冗长的xml不成问题,可以使用xmlrpc_encode从数组创建xml。 www.php.net/xmlrpc_encode
注意,如果使用关联键和/或数字键,创建的XML会有所不同
<?php
// /params/param/value/struct/member
// there is a tag "member" for each element
// "member" contains a tag "name". its value is the associative key
$xml1 = xmlrpc_encode(array('a'=>'b','c'=>'d'));
$simplexml1 = simplexml_load_string($xml1);
print_r($xml1);
print_r($simplexml1);
// /params/param/value/array/data
// there is a tag "data" for each element
// "data" doesn't contain the tag "name"
$xml2 = xmlrpc_encode(array('a','b'));
$simplexml2 = simplexml_load_string($xml2);
print_r($xml2);
print_r($simplexml2);
?>
基于这里的所有其他内容,通过前缀@处理数值索引+属性,并可以将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
以上答案大部分是正确的。然而,我想出了这个答案,它解决了array_walk_recursive的兼容性问题,也解决了数值键的问题。它也通过了我做的所有测试:
function arrayToXML(Array $array, SimpleXMLElement &$xml) {
foreach($array as $key => $value) {
// None array
if (!is_array($value)) {
(is_numeric($key)) ? $xml->addChild("item$key", $value) : $xml->addChild($key, $value);
continue;
}
// Array
$xmlChild = (is_numeric($key)) ? $xml->addChild("item$key") : $xml->addChild($key);
arrayToXML($value, $xmlChild);
}
}
我还为此添加了一个测试类,你可能会发现有用:
class ArrayToXmlTest extends PHPUnit_Framework_TestCase {
public function setUp(){ }
public function tearDown(){ }
public function testFuncExists() {
$this->assertTrue(function_exists('arrayToXML'));
}
public function testFuncReturnsXml() {
$array = array(
'name' => 'ardi',
'last_name' => 'eshghi',
'age' => 31,
'tel' => '0785323435'
);
$xmlEl = new SimpleXMLElement('<root/>');
arrayToXml($array, $xmlEl);
$this->assertTrue($xmlEl instanceOf SimpleXMLElement);
}
public function testAssocArrayToXml() {
$array = array(
'name' => 'ardi',
'last_name' => 'eshghi',
'age' => 31,
'tel' => '0785323435'
);
$expectedXmlEl = new SimpleXMLElement('<root/>');
$expectedXmlEl->addChild('name', $array['name']);
$expectedXmlEl->addChild('last_name', $array['last_name']);
$expectedXmlEl->addChild('age', $array['age']);
$expectedXmlEl->addChild('tel', $array['tel']);
$actualXmlEl = new SimpleXMLElement('<root/>');
arrayToXml($array, $actualXmlEl);
$this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML());
}
public function testNoneAssocArrayToXml() {
$array = array(
'ardi',
'eshghi',
31,
'0785323435'
);
// Expected xml value
$expectedXmlEl = new SimpleXMLElement('<root/>');
foreach($array as $key => $value)
$expectedXmlEl->addChild("item$key", $value);
// What the function produces
$actualXmlEl = new SimpleXMLElement('<root/>');
arrayToXml($array, $actualXmlEl);
$this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML());
}
public function testNestedMixArrayToXml() {
$testArray = array(
"goal",
"nice",
"funny" => array(
'name' => 'ardi',
'tel' =>'07415517499',
"vary",
"fields" => array(
'small',
'email' => 'ardi.eshghi@gmail.com'
),
'good old days'
),
"notes" => "come on lads lets enjoy this",
"cast" => array(
'Tom Cruise',
'Thomas Muller' => array('age' => 24)
)
);
// Expected xml value
$expectedXmlEl = new SimpleXMLElement('<root/>');
$expectedXmlEl->addChild('item0', $testArray[0]);
$expectedXmlEl->addChild('item1', $testArray[1]);
$childEl = $expectedXmlEl->addChild('funny');
$childEl->addChild("name", $testArray['funny']['name']);
$childEl->addChild("tel", $testArray['funny']['tel']);
$childEl->addChild("item0", "vary");
$childChildEl = $childEl->addChild("fields");
$childChildEl->addChild('item0', 'small');
$childChildEl->addChild('email', $testArray['funny']['fields']['email']);
$childEl->addChild("item1", 'good old days');
$expectedXmlEl->addChild('notes', $testArray['notes']);
$childEl2 = $expectedXmlEl->addChild('cast');
$childEl2->addChild('item0', 'Tom Cruise');
$childChildEl2 = $childEl2->addChild('Thomas Muller');
$childChildEl2->addChild('age', $testArray['cast']['Thomas Muller']['age']);
// What the function produces
$actualXmlEl = new SimpleXMLElement('<root/>');
arrayToXml($testArray, $actualXmlEl);
$this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->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();
使用FluidXML,您可以从一个PHP数组开始,生成一个用于SimpleXML的XML…只有两行代码。
$fluidxml = fluidxml($array);
$simplexml = simplexml_import_dom($fluidxml->dom());
一个示例数组可以是
$array = [ 'doc' => [
'fruit' => 'orange',
'cake' => [
'@id' => '123',
'@' => 'tiramisu' ],
[ 'pasta' => 'matriciana' ],
[ 'pasta' => 'boscaiola' ]
] ];
https://github.com/servo-php/fluidxml