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


当前回答

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

其他回答

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

如果数组是关联的并且键是正确的,那么首先将它转换为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”用于数组的每个节点。

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

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

<?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();

我的答案,拼凑别人的答案。这应该可以纠正无法补偿数字键的错误:

function array_to_xml($array, $root, $element) {
    $xml = new SimpleXMLElement("<{$root}/>");
    foreach ($array as $value) {
        $elem = $xml->addChild($element);
        xml_recurse_child($elem, $value);
    }
    return $xml;
}

function xml_recurse_child(&$node, $child) {
    foreach ($child as $key=>$value) {
        if(is_array($value)) {
            foreach ($value as $k => $v) {
                if(is_numeric($k)){
                    xml_recurse_child($node, array($key => $v));
                }
                else {
                    $subnode = $node->addChild($key);
                    xml_recurse_child($subnode, $value);
                }
            }
        }
        else {
            $node->addChild($key, $value);
        }
    }   
}

array_to_xml()函数假定数组首先由数字键组成。如果数组有一个初始元素,则可以从array_to_xml()函数中删除foreach()和$elem语句,只传递$xml。