如何将数组转换为PHP中的SimpleXML对象?
当前回答
另一个改进:
/**
* Converts an array to XML
*
* @param array $array
* @param SimpleXMLElement $xml
* @param string $child_name
*
* @return SimpleXMLElement $xml
*/
public function arrayToXML($array, SimpleXMLElement $xml, $child_name)
{
foreach ($array as $k => $v) {
if(is_array($v)) {
(is_int($k)) ? $this->arrayToXML($v, $xml->addChild($child_name), $v) : $this->arrayToXML($v, $xml->addChild(strtolower($k)), $child_name);
} else {
(is_int($k)) ? $xml->addChild($child_name, $v) : $xml->addChild(strtolower($k), $v);
}
}
return $xml->asXML();
}
用法:
$this->arrayToXML($array, new SimpleXMLElement('<root/>'), 'child_name_to_replace_numeric_integers');
其他回答
以上答案大部分是正确的。然而,我想出了这个答案,它解决了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());
}
}
只是对上面的函数进行了编辑,当键是数字时,添加前缀“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");
}
}
}
}
这里有一个函数帮我解决了这个问题:
就像这样叫它
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;
}
}
你可以使用胡子模板引擎,并制作一个模板,如:
{{#RECEIVER}}
<RECEIVER>
<COMPANY>{{{COMPANY}}}</COMPANY>
<CONTACT>{{{CONTACT}}}</CONTACT>
<ADDRESS>{{{ADDRESS}}}</ADDRESS>
<ZIP>{{ZIP}}</ZIP>
<CITY>{{{CITY}}}</CITY>
</RECEIVER>
{{/RECEIVER}}
{{#DOC}}
<DOC>
<TEXT>{{{TEXT}}}</TEXT>
<NUMBER>{{{NUMBER}}}</NUMBER>
</DOC>
{{/DOC}}
在PHP中这样使用它:
require_once( __DIR__ .'/../controls/Mustache/Autoloader.php' );
Mustache_Autoloader::register();
$oMustache = new Mustache_Engine();
$sTemplate = implode( '', file( __DIR__ ."/xml.tpl" ));
$return = $oMustache->render($sTemplate, $res);
echo($return);
// Structered array for XML convertion. $data_array = array( array( '#xml_tag' => 'a', '#xml_value' => '', '#tag_attributes' => array( array( 'name' => 'a_attr_name', 'value' => 'a_attr_value', ), ), '#subnode' => array( array( '#xml_tag' => 'aa', '#xml_value' => 'aa_value', '#tag_attributes' => array( array( 'name' => 'aa_attr_name', 'value' => 'aa_attr_value', ), ), '#subnode' => FALSE, ), ), ), array( '#xml_tag' => 'b', '#xml_value' => 'b_value', '#tag_attributes' => FALSE, '#subnode' => FALSE, ), array( '#xml_tag' => 'c', '#xml_value' => 'c_value', '#tag_attributes' => array( array( 'name' => 'c_attr_name', 'value' => 'c_attr_value', ), array( 'name' => 'c_attr_name_1', 'value' => 'c_attr_value_1', ), ), '#subnode' => array( array( '#xml_tag' => 'ca', '#xml_value' => 'ca_value', '#tag_attributes' => FALSE, '#subnode' => array( array( '#xml_tag' => 'caa', '#xml_value' => 'caa_value', '#tag_attributes' => array( array( 'name' => 'caa_attr_name', 'value' => 'caa_attr_value', ), ), '#subnode' => FALSE, ), ), ), ), ), ); // creating object of SimpleXMLElement $xml_object = new SimpleXMLElement('<?xml version=\"1.0\"?><student_info></student_info>'); // function call to convert array to xml array_to_xml($data_array, $xml_object); // saving generated xml file $xml_object->asXML('/tmp/test.xml'); /** * Converts an structured PHP array to XML. * * @param Array $data_array * The array data for converting into XML. * @param Object $xml_object * The SimpleXMLElement Object * * @see https://gist.github.com/drupalista-br/9230016 * */ function array_to_xml($data_array, &$xml_object) { foreach($data_array as $node) { $subnode = $xml_object->addChild($node['#xml_tag'], $node['#xml_value']); if ($node['#tag_attributes']) { foreach ($node['#tag_attributes'] as $tag_attributes) { $subnode->addAttribute($tag_attributes['name'], $tag_attributes['value']); } } if ($node['#subnode']) { array_to_xml($node['#subnode'], $subnode); } } }