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


当前回答

使用FluidXML,您可以从一个PHP数组开始,生成一个用于SimpleXML的XML…只有两行代码。

$fluidxml  = fluidxml($array);
$simplexml = simplexml_import_dom($fluidxml->dom());

一个示例数组可以是

$array = [ 'doc' => [
              'fruit' => 'orange',
              'cake'  => [
                   '@id' => '123', 
                   '@'   => 'tiramisu' ],
              [ 'pasta' => 'matriciana' ],
              [ 'pasta' => 'boscaiola'  ]
] ];

https://github.com/servo-php/fluidxml

其他回答

一个简短的例子:

<?php

$test_array = array (
  'bla' => 'blub',
  'foo' => 'bar',
  'another_array' => array (
    'stack' => 'overflow',
  ),
);
$xml = new SimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
print $xml->asXML();

结果

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

键和值会被交换——你可以在array_walk之前用array_flip()来修复这个问题。array_walk_recursive需要PHP 5。你可以用array_walk代替,但你不会得到'stack' => 'overflow'在XML中。

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

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

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

测试数组

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

下面是php 5.2代码,将数组的任何深度转换为xml文档:

Array
(
    ['total_stud']=> 500
    [0] => Array
        (
            [student] => Array
                (
                    [id] => 1
                    [name] => abc
                    [address] => Array
                        (
                            [city]=>Pune
                            [zip]=>411006
                        )                       
                )
        )
    [1] => Array
        (
            [student] => Array
                (
                    [id] => 2
                    [name] => xyz
                    [address] => Array
                        (
                            [city]=>Mumbai
                            [zip]=>400906
                        )   
                )

        )
)

生成的XML如下所示:

<?xml version="1.0"?>
<student_info>
    <total_stud>500</total_stud>
    <student>
        <id>1</id>
        <name>abc</name>
        <address>
            <city>Pune</city>
            <zip>411006</zip>
        </address>
    </student>
    <student>
        <id>1</id>
        <name>abc</name>
        <address>
            <city>Mumbai</city>
            <zip>400906</zip>
        </address>
    </student>
</student_info>

PHP代码片段

<?php
// function defination to convert array to xml
function array_to_xml( $data, &$xml_data ) {
    foreach( $data as $key => $value ) {
        if( is_array($value) ) {
            if( is_numeric($key) ){
                $key = 'item'.$key; //dealing with <0/>..<n/> issues
            }
            $subnode = $xml_data->addChild($key);
            array_to_xml($value, $subnode);
        } else {
            $xml_data->addChild("$key",htmlspecialchars("$value"));
        }
     }
}

// initializing or creating array
$data = array('total_stud' => 500);

// creating object of SimpleXMLElement
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');

// function call to convert array to xml
array_to_xml($data,$xml_data);

//saving generated xml file; 
$result = $xml_data->asXML('/file/path/name.xml');

?>

本代码段中使用的SimpleXMLElement::asXML文档

这里提供的答案仅将数组转换为带节点的XML,不能设置属性。我已经编写了一个php函数,允许您将数组转换为php,并为xml中的特定节点设置属性。这里的缺点是您必须以很少约定的特定方式构造数组(仅当您想使用属性时)

下面的示例也允许您用XML设置属性。

来源可以在这里找到: https://github.com/digitickets/lalit/blob/master/src/Array2XML.php

<?php    
$books = array(
    '@attributes' => array(
        'type' => 'fiction'
    ),
    'book' => array(
        array(
            '@attributes' => array(
                'author' => 'George Orwell'
            ),
            'title' => '1984'
        ),
        array(
            '@attributes' => array(
                'author' => 'Isaac Asimov'
            ),
            'title' => 'Foundation',
            'price' => '$15.61'
        ),
        array(
            '@attributes' => array(
                'author' => 'Robert A Heinlein'
            ),
            'title' => 'Stranger in a Strange Land',
            'price' => array(
                '@attributes' => array(
                    'discount' => '10%'
                ),
                '@value' => '$18.00'
            )
        )
    )
);
/* creates 
<books type="fiction">
  <book author="George Orwell">
    <title>1984</title>
  </book>
  <book author="Isaac Asimov">
    <title>Foundation</title>
    <price>$15.61</price>
  </book>
  <book author="Robert A Heinlein">
    <title>Stranger in a Strange Land</title>
    <price discount="10%">$18.00</price>
  </book>
</books>
*/
?>