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


当前回答

下面是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可能会更容易。喜欢的东西:

  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”用于数组的每个节点。

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

只是对上面的函数进行了编辑,当键是数字时,添加前缀“key_”

// initializing or creating array
$student_info = array(your array data);

// creating object of SimpleXMLElement
$xml_student_info = new SimpleXMLElement("<?xml version=\"1.0\"?><student_info></student_info>");

// function call to convert array to xml
array_to_xml($student,$xml_student_info);

//saving generated xml file
$xml_student_info->asXML('file path and name');


function array_to_xml($student_info, &$xml_student_info) {
     foreach($student_info as $key => $value) {
          if(is_array($value)) {
            if(!is_numeric($key)){
                $subnode = $xml_student_info->addChild("$key");
                array_to_xml($value, $subnode);
            }
            else{
                $subnode = $xml_student_info->addChild("key_$key");
                array_to_xml($value, $subnode);
            }
          }
          else {
               if(!is_numeric($key)){
                    $xml_student_info->addChild("$key","$value");
               }else{
                    $xml_student_info->addChild("key_$key","$value");
               }
          }
     }
}

我发现这个解与原来的问题相似

<?php

$test_array = array (
  'bla' => 'blub',
  'foo' => 'bar',
  'another_array' => array (
    'stack' => 'overflow',
  ),
);

class NoSimpleXMLElement extends SimpleXMLElement {
 public function addChild($name,$value) {
  parent::addChild($value,$name);
 }
}
$xml = new NoSimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
print $xml->asXML();

我认为上面所有的解决方案都很好,但我看到目前为止,它并没有真正创建一个准确的格式良好的XML,因为数组键与$my_array[main_node][multiple_values][] = ARRAY ('id' => '1')然后转换为

    <main_node>
       <multiple_values>
         <0>
           <id>1 test</id>
         </0>
       </multiple_values>
       <multiple_values>
         <1>
          <id>2 test</id>
         </1>
       </multiple_values>
    </main_node>

这是XML解析器方面的一个问题……

I should be like this:

    <main_node>
     <multiple_values>
      <id>1 test</id>
     </multiple_values>
     <multiple_values>
      <id>2 test</id>
     </multiple_values>
    </main_node>

如果你用load_simple_xml来解析…你会得到完全相同的数组/对象结构。

我的函数还自动创建正确的根节点。

    // Code to convert php array to xml document 20211112
    function array2xml(array $data, $xml_class_obj = '', $group_by_parent_allowed = '', $options = array())
        {   
            
            if(!$xml_class_obj) :
                $is_root = 1;
                $xml_class_obj = new XMLWriter();
                $xml_class_obj->openMemory();
                $xml_class_obj->setIndent(TRUE);
                $xml_class_obj->setIndentString('   ');
                if($options['encoding'] != '')  $xml_class_obj->startDocument('1.0', $options['encoding']);
                else                                                        $xml_class_obj->startDocument('1.0');
            endif;
            
            foreach ($data as $key => $value) {

                if (is_array($value)) { // IS ARRAY

                    // check if allow below keys are int, if yes group them to same parent tree
                    $group_by_parent = $key;
                    foreach(array_keys($value) as $c_keys) :
                        if(!is_int($c_keys)) $group_by_parent = '';
                    endforeach;

                    if(empty($group_by_parent)) $xml_class_obj->startElement($key); 
                    if($group_by_parent_allowed != '') $xml_class_obj->startElement($group_by_parent_allowed);
                    
                    $this->array2xml($value, $xml_class_obj, $group_by_parent, $options);
                    
                    if(empty($group_by_parent)) $xml_class_obj->endElement();  

                } else { // IS VALUE
                    
                    if(is_string($value)) :
                        $xml_class_obj->startElement($key);
                        $xml_class_obj->writeCData($value);         
                        $xml_class_obj->endElement();           
                    else :
                        $xml_class_obj->writeElement($key, $value); 
                    endif;

                }

            } // foreach
            
            if($group_by_parent_allowed != '')  $xml_class_obj->endElement(); 
            
            if($is_root == 1) :
            
                $xml_class_obj->endDocument();
                return $xml_class_obj->outputMemory();
            else :              
                return $xml_class_obj;                  
            endif;
              
        }  
    
    // usage
    $ary_new_xml = array();
    $ary_new_xml['order']['customer']['customerid'] = '123456'; 
    $ary_new_xml['order']['customer']['customertype'] = 15; 
            
    $ary_new_xml['order']['orderprio'] = 2; 
            
    $ary_new_xml['order']['orderpos'][] = array('sku' => 9999910001111, 'quantity' => 3);           
    $ary_new_xml['order']['orderpos'][] = array('sku' => 9999910002222, 'quantity' => 1); 
            
echo array2xml($ary_new_xml,'','',array('enconding' => 'UTF-8'));

结果:

<?xml version="1.0" encoding="UTF-8"?>
<order>
   <customer>
      <customerid>82936639</customerid>
      <customertype>15</customertype>
   </customer>
   <orderprio>2</orderprio>
   <orderpos>
      <sku>9999910001111</sku>
      <quantity>3</quantity>
   </orderpos>
   <orderpos>
      <sku>9999910002222</sku>
      <quantity>1</quantity>
   </orderpos>
</order>


 

我希望这能帮助到一些人;)

您可以使用我一直在研究的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>