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


当前回答

整个XML结构定义在$data数组中:

function array2Xml($data, $xml = null)
{
    if (is_null($xml)) {
        $xml = simplexml_load_string('<' . key($data) . '/>');
        $data = current($data);
        $return = true;
    }
    if (is_array($data)) {
        foreach ($data as $name => $value) {
            array2Xml($value, is_numeric($name) ? $xml : $xml->addChild($name));
        }
    } else {
        $xml->{0} = $data;
    }
    if (!empty($return)) {
        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”用于数组的每个节点。

稍后我将尝试使用这两个版本来更新这篇文章。

你可以使用胡子模板引擎,并制作一个模板,如:

{{#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);

这里有一个函数帮我解决了这个问题:

就像这样叫它

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;
        }
    }

下面讨论名称空间。在本例中,构造包装器以包含名称空间定义,并将其传递给函数。使用冒号来标识命名空间。

测试数组

$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);
        }   
    }   
}   

其他解决方案:

$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);