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


当前回答

我认为上面所有的解决方案都很好,但我看到目前为止,它并没有真正创建一个准确的格式良好的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>


 

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

其他回答

使用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

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

如果冗长的xml不成问题,可以使用xmlrpc_encode从数组创建xml。 www.php.net/xmlrpc_encode

注意,如果使用关联键和/或数字键,创建的XML会有所不同

<?php
// /params/param/value/struct/member
// there is a tag "member" for each element
// "member" contains a tag "name". its value is the associative key
$xml1 = xmlrpc_encode(array('a'=>'b','c'=>'d'));
$simplexml1 = simplexml_load_string($xml1);
print_r($xml1);
print_r($simplexml1);

// /params/param/value/array/data
// there is a tag "data" for each element
// "data" doesn't contain the tag "name"
$xml2 = xmlrpc_encode(array('a','b'));
$simplexml2 = simplexml_load_string($xml2);
print_r($xml2);
print_r($simplexml2);
?>

另一个改进:

/**
* Converts an array to XML
*
* @param array $array
* @param SimpleXMLElement $xml
* @param string $child_name
*
* @return SimpleXMLElement $xml
*/
public function arrayToXML($array, SimpleXMLElement $xml, $child_name)
{
    foreach ($array as $k => $v) {
        if(is_array($v)) {
            (is_int($k)) ? $this->arrayToXML($v, $xml->addChild($child_name), $v) : $this->arrayToXML($v, $xml->addChild(strtolower($k)), $child_name);
        } else {
            (is_int($k)) ? $xml->addChild($child_name, $v) : $xml->addChild(strtolower($k), $v);
        }
    }

    return $xml->asXML();
}

用法:

$this->arrayToXML($array, new SimpleXMLElement('<root/>'), 'child_name_to_replace_numeric_integers');

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