如何将数组转换为PHP中的SimpleXML对象?


当前回答

您也可以通过DOM来实现这一点。请参阅下面的代码。

<?php

$el = array();
$command = array();

$dom = new DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;

$xml_array = [
    'root'=>[
    'Good guy' => [
        'name' => [
            '_cdata' => 'Luke Skywalker'
        ],
        'weapon' => 'Lightsaber'
    ],
    'Bad guy' => [
        'name' => 'Sauron',
        'weapon' => 'Evil Eye'
    ]
        ]
];

convert_xml($xml_array);

if(!empty($el))
{
    $dom->appendChild(end($el));
}

echo $dom->saveXML();

?>

<?php

 function convert_xml($Xml)
{
    global $el, $dom;

        foreach($Xml as $id=>$val)
        {
            if(is_numeric($id))
            {
                $id = "Item".($id);
            }

            $id = str_replace(' ', '-', strtolower($id));

            if(is_array($val))
            {
                $ele = $dom->createElement($id);
                array_push($el, $ele);
                convert_xml($val);
            }
            else
            {
                $ele = $dom->createElement($id, $val);

                if(!empty($el))
                {
                    $com = end($el)->appendChild($ele);
                }
                else
                {
                    $dom->appendChild($ele);
                }

            }
        }

        if(sizeof($el) > 1)
        {
            $child = end($el);
            $com = prev($el)->appendChild($child);
            array_pop($el);
        }
}

?>

其他回答

我想要一个代码,将一个数组内的所有元素,并把它们作为属性,所有数组作为子元素。

对于像这样的东西

array (
'row1' => array ('head_element' =>array("prop1"=>"some value","prop2"=>array("empty"))),
"row2"=> array ("stack"=>"overflow","overflow"=>"overflow")
);

我会得到这样的结果

<?xml version="1.0" encoding="utf-8"?>
<someRoot>
  <row1>
    <head_element prop1="some value">
      <prop2 0="empty"/>
    </head_element>
  </row1>
  <row2 stack="overflow" overflow="stack"/>
 </someRoot>

要实现这一点,代码如下,但要非常小心,它是递归的,实际上可能会导致stackoverflow:)

function addElements(&$xml,$array)
{
$params=array();
foreach($array as $k=>$v)
{
    if(is_array($v))
        addElements($xml->addChild($k), $v);
    else $xml->addAttribute($k,$v);
}

}
function xml_encode($array)
{
if(!is_array($array))
    trigger_error("Type missmatch xml_encode",E_USER_ERROR);
$xml=new SimpleXMLElement('<?xml version=\'1.0\' encoding=\'utf-8\'?><'.key($array).'/>');
addElements($xml,$array[key($array)]);
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 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();
}

您可以使用我一直在研究的XMLParser。

$xml = XMLParser::encode(array(
    'bla' => 'blub',
    'foo' => 'bar',
    'another_array' => array (
        'stack' => 'overflow',
    )
));
// @$xml instanceof SimpleXMLElement
echo $xml->asXML();

会导致:

<?xml version="1.0"?>
<root>
    <bla>blub</bla>
    <foo>bar</foo>
    <another_array>
        <stack>overflow</stack>
    </another_array>
</root>

另一个改进:

/**
* 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');