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


当前回答

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

就像这样叫它

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

其他回答

如果你使用magento,你有这种类型的关联数组

$test_array = array (
    '0' => array (
            'category_id' => '582',
            'name' => 'Surat',
            'parent_id' => '565',
            'child_id' => '567',
            'active' => '1',
            'level' => '6',
            'position' => '17'
    ),

    '1' => array (
            'category_id' => '567', 
            'name' => 'test',
            'parent_id' => '0',
            'child_id' => '576',
            'active' => '0',
            'level' => '0',
            'position' => '18'
    ),
);

那么最好将关联数组转换为XML格式。在控制器文件中使用此代码。

$this->loadLayout(false);
//header ("content-type: text/xml");
$this->getResponse()->setHeader('Content-Type','text/xml');
$this->renderLayout();

$clArr2xml = new arr2xml($test_array, 'utf-8', 'listdata');
$output = $clArr2xml->get_xml();
print $output; 

class arr2xml
{
var $array = array();
var $xml = '';
var $root_name = '';
var $charset = '';

public function __construct($array, $charset = 'utf-8', $root_name = 'root')
{
    header ("content-type: text/xml");
    $this->array = $array;
    $this->root_name = $root_name;
    $this->charset = $charset;

    if (is_array($array) && count($array) > 0) {
        $this->struct_xml($array);

    } else {
        $this->xml .= "no data";
    }
}

public function struct_xml($array)
{
    foreach ($array as $k => $v) {
        if (is_array($v)) {
            $tag = ereg_replace('^[0-9]{1,}', 'item', $k); // replace numeric key in array to 'data'
            $this->xml .= "<$tag>";
            $this->struct_xml($v);
            $this->xml .= "</$tag>";
        } else {
            $tag = ereg_replace('^[0-9]{1,}', 'item', $k); // replace numeric key in array to 'data'
            $this->xml .= "<$tag><![CDATA[$v]]></$tag>";
        }
    }
}

public function get_xml()
{

    $header = "<?xml version=\"1.0\" encoding=\"" . $this->charset . "\"?><" . $this->root_name . ">";
    $footer = "</" . $this->root_name . ">";

    return $header . $this->xml . $footer;
}
}

我希望这对大家都有帮助。

function array2xml(array $data, SimpleXMLElement $object = null, $oldNodeName = 'item')
{
    if (is_null($object)) $object = new SimpleXMLElement('<root/>');
    $isNumbered = true;
    $idx = 0;
    foreach ($data as $key => $x)
        if (is_string($key) || ($idx++ != $key + 0))
            $isNumbered = false;
    foreach ($data as $key => $value)
    {   
        $attribute = preg_match('/^[0-9]/', $key . '') ? $key : null;
        $key = (is_string($key) && !preg_match('/^[0-9]/', $key . '')) ? $key : preg_replace('/s$/', '', $oldNodeName);
        if (is_array($value))
        {
            $new_object = $object->addChild($key);
            if (!$isNumbered && !is_null($attribute)) $new_object->addAttribute('id', $attribute);
            array2xml($value, $new_object, $key);
        }
        else
        {
            if (is_bool($value)) $value = $value ? 'true' : 'false';
            $node = $object->addChild($key, htmlspecialchars($value));
            if (!$isNumbered && !is_null($attribute) && !isset($node->attributes()->id))
                $node->addAttribute('id', $attribute);
        }
    }
    return $object;
}

例如,该函数返回一个<obj>…</obj><obj>…</obj>数值索引的XML标记。

输入:

    array(
    'people' => array(
        'dog',
        'cat',
        'life' => array(
            'gum',
            'shoe',
        ),
        'fish',
    ),
    array('yeah'),
)

输出:

<root>
    <people>
        <people>dog</people>
        <people>cat</people>
        <life>
            <life>gum</life>
            <life>shoe</life>
        </life>
        <people>fish</people>
        <people>
            <people>yeah</people>
        </people>
    </people>
</root>

这应该能满足所有的共同需求。也许你可以把第三行改成:

$key = is_string($key) ? $key : $oldNodeName . '_' . $key;

或者如果你正在处理以s结尾的复数:

$key = is_string($key) ? $key : preg_replace('/s$/', '', $oldNodeName);

您也可以通过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);
        }
}

?>
function toXML($data, $obj = false, $dom) {
    $is_first_level = false;
    if($obj === false) {
        $dom = new DomDocument('1.0');
        $obj = $dom;
        $is_first_level = true;
    }

    if(is_array($data)) {
        foreach($data as $key => $item) {
            $this->toXML($item, $obj->appendChild($dom->createElement($key)), $dom);
        }
    }else {
        $obj->appendChild($dom->createTextNode($data));
    }

    if($is_first_level) {
        $obj->formatOutput = true;
        return $obj->saveXML();
    }
    return $obj;
}

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

测试数组

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