代码之家  ›  专栏  ›  技术社区  ›  mik

如何将数组转换为SimpleXML

  •  266
  • mik  · 技术社区  · 17 年前

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

    32 回复  |  直到 15 年前
        1
  •  410
  •   Francisco R    6 年前

    以下是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');
    
    ?>
    

    Documentation on SimpleXMLElement::asXML used in this snippet

        2
  •  223
  •   ax. Clement Herreman    16 年前

    <?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_flip() 在你走之前。 array_walk_recursive 需要PHP5。你可以用 array_walk 相反,但你不会得到 'stack' => 'overflow' 然后在xml中。

        3
  •  136
  •   Gold Paweł Fus    7 年前

    下面的示例也允许您在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>
    */
    ?>
    
        4
  •  60
  •   Francis Lewis    5 年前

    我发现所有的答案都使用了太多的代码。下面是一个简单的方法:

    function to_xml(SimpleXMLElement $object, array $data)
    {   
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $new_object = $object->addChild($key);
                to_xml($new_object, $value);
            } else {
                // if the key is an integer, it needs text with it to actually work.
                if ($key != 0 && $key == (int) $key) {
                    $key = "key_$key";
                }
    
                $object->addChild($key, $value);
            }   
        }   
    }   
    

    $xml = new SimpleXMLElement('<rootTag/>');
    to_xml($xml, $my_array);
    

    现在,$xml包含了一个漂亮的xml对象,它完全基于数组的编写方式。

    print $xml->asXML();
    
        5
  •  38
  •   onokazu    16 年前
    函数数组到xml(数组$arr,simplexmlement$xml)
    foreach($arr as$k=>$v){
    is_阵列($v)
    ? 数组到xml($v,$xml->addChild($k))
    :$xml->addChild($k,$v);
    }
    }
    
    $test\u数组=数组(
    “bla”=>'蓝色',
    “foo”=>'酒吧‘,
    “另一个数组”=>排列(
    “堆栈”=>'溢出',
    );
    
    echo数组到xml($test数组,新的simplexmlement('<root/>'))->asXML();
    
        6
  •  19
  •   user492589    11 年前

    来自PHP5.4

    function array2xml($data, $root = null){
        $xml = new SimpleXMLElement($root ? '<' . $root . '/>' : '<root/>');
        array_walk_recursive($data, function($value, $key)use($xml){
            $xml->addChild($key, $value);
        });
        return $xml->asXML();
    }
    
        7
  •  15
  •   Syl    12 年前

    另一项改进:

    /**
    * 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');
    
        8
  •  12
  •   Frans van Asselt    15 年前

    这是我的作品,简单明了。。

    function array2xml($array, $xml = false){
        if($xml === false){
            $xml = new SimpleXMLElement('<root/>');
        }
        foreach($array as $key => $value){
            if(is_array($value)){
                array2xml($value, $xml->addChild($key));
            }else{
                $xml->addChild($key, $value);
            }
        }
        return $xml->asXML();
    }
    
    
    header('Content-type: text/xml');
    print array2xml($array);
    
        9
  •  8
  •   CodePT    13 年前

     <?php
    
    function array_to_xml(array $arr, SimpleXMLElement $xml) {
            foreach ($arr as $k => $v) {
    
                $attrArr = array();
                $kArray = explode(' ',$k);
                $tag = array_shift($kArray);
    
                if (count($kArray) > 0) {
                    foreach($kArray as $attrValue) {
                        $attrArr[] = explode('=',$attrValue);                   
                    }
                }
    
                if (is_array($v)) {
                    if (is_numeric($k)) {
                        array_to_xml($v, $xml);
                    } else {
                        $child = $xml->addChild($tag);
                        if (isset($attrArr)) {
                            foreach($attrArr as $attrArrV) {
                                $child->addAttribute($attrArrV[0],$attrArrV[1]);
                            }
                        }                   
                        array_to_xml($v, $child);
                    }
                } else {
                    $child = $xml->addChild($tag, $v);
                    if (isset($attrArr)) {
                        foreach($attrArr as $attrArrV) {
                            $child->addAttribute($attrArrV[0],$attrArrV[1]);
                        }
                    }
                }               
            }
    
            return $xml;
        }
    
            $test_array = array (
              'bla' => 'blub',
              'foo' => 'bar',
              'another_array' => array (
                array('stack' => 'overflow'),
                array('stack' => 'overflow'),
                array('stack' => 'overflow'),
              ),
              'foo attribute1=value1 attribute2=value2' => 'bar',
            );  
    
            $xml = array_to_xml($test_array, new SimpleXMLElement('<root/>'))->asXML();
    
            echo "$xml\n";
            $dom = new DOMDocument;
            $dom->preserveWhiteSpace = FALSE;
            $dom->loadXML($xml);
            $dom->formatOutput = TRUE;
            echo $dom->saveXml();
        ?>
    
        10
  •  5
  •   lcornea    13 年前

    我想要一个代码,它将获取数组中的所有元素,并将它们作为属性,将所有数组作为子元素。

    比如说

    array (
    'row1' => array ('head_element' =>array("prop1"=>"some value","prop2"=>array("empty"))),
    "row2"=> array ("stack"=>"overflow","overflow"=>"overflow")
    );
    

    <?xml version="1.0" encoding="utf-8"?>
    <someRoot>
      <row1>
        <head_element prop1="some value">
          <prop2 0="empty"/>
        </head_element>
      </row1>
      <row2 stack="overflow" overflow="stack"/>
     </someRoot>
    

    要实现这一点,代码如下所示,但要非常小心,它是递归的,实际上可能会导致堆栈溢出:)

    function addElements(&$xml,$array)
    {
    $params=array();
    foreach($array as $k=>$v)
    {
        if(is_array($v))
            addElements($xml->addChild($k), $v);
        else $xml->addAttribute($k,$v);
    }
    
    }
    function xml_encode($array)
    {
    if(!is_array($array))
        trigger_error("Type missmatch xml_encode",E_USER_ERROR);
    $xml=new SimpleXMLElement('<?xml version=\'1.0\' encoding=\'utf-8\'?><'.key($array).'/>');
    addElements($xml,$array[key($array)]);
    return $xml->asXML();
    } 
    

        11
  •  4
  •   Neil English    14 年前

    我使用我不久前编写的两个函数来生成xml,以便从PHP和jQuery等中来回传递。。。

    如果它对任何人都有用,请使用它:)

    function generateXML($tag_in,$value_in="",$attribute_in=""){
        $return = "";
        $attributes_out = "";
        if (is_array($attribute_in)){
            if (count($attribute_in) != 0){
                foreach($attribute_in as $k=>$v):
                    $attributes_out .= " ".$k."=\"".$v."\"";
                endforeach;
            }
        }
        return "<".$tag_in."".$attributes_out.((trim($value_in) == "") ? "/>" : ">".$value_in."</".$tag_in.">" );
    }
    
    function arrayToXML($array_in){
        $return = "";
        $attributes = array();
        foreach($array_in as $k=>$v):
            if ($k[0] == "@"){
                // attribute...
                $attributes[str_replace("@","",$k)] = $v;
            } else {
                if (is_array($v)){
                    $return .= generateXML($k,arrayToXML($v),$attributes);
                    $attributes = array();
                } else if (is_bool($v)) {
                    $return .= generateXML($k,(($v==true)? "true" : "false"),$attributes);
                    $attributes = array();
                } else {
                    $return .= generateXML($k,$v,$attributes);
                    $attributes = array();
                }
            }
        endforeach;
        return $return;
    }   
    

    爱所有人:)

        12
  •  4
  •   jtrumbull    12 年前

    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>
    
        13
  •  4
  •   drzaus tranceporter    12 年前

    基于这里的所有其他内容,通过使用前缀处理数字索引+属性 @ ,并可以将xml注入现有节点:

    密码

    function simple_xmlify($arr, SimpleXMLElement $root = null, $el = 'x') {
        // based on, among others http://stackoverflow.com/a/1397164/1037948
    
        if(!isset($root) || null == $root) $root = new SimpleXMLElement('<' . $el . '/>');
    
        if(is_array($arr)) {
            foreach($arr as $k => $v) {
                // special: attributes
                if(is_string($k) && $k[0] == '@') $root->addAttribute(substr($k, 1),$v);
                // normal: append
                else simple_xmlify($v, $root->addChild(
                        // fix 'invalid xml name' by prefixing numeric keys
                        is_numeric($k) ? 'n' . $k : $k)
                    );
            }
        } else {
            $root[0] = $arr;
        }
    
        return $root;
    }//--   fn  simple_xmlify
    

    用法

    // lazy declaration via "queryparam"
    $args = 'hello=4&var[]=first&var[]=second&foo=1234&var[5]=fifth&var[sub][]=sub1&var[sub][]=sub2&var[sub][]=sub3&var[@name]=the-name&var[@attr2]=something-else&var[sub][@x]=4.356&var[sub][@y]=-9.2252';
    $q = array();
    parse_str($val, $q);
    
    $xml = simple_xmlify($q); // dump $xml, or...
    $result = get_formatted_xml($xml); // see below
    

    后果

    <?xml version="1.0"?>
    <x>
      <hello>4</hello>
      <var name="the-name" attr2="something-else">
        <n0>first</n0>
        <n1>second</n1>
        <n5>fifth</n5>
        <sub x="4.356" y="-9.2252">
          <n0>sub1</n0>
          <n1>sub2</n1>
          <n2>sub3</n2>
        </sub>
      </var>
      <foo>1234</foo>
    </x>
    

    好处:格式化XML

    function get_formatted_xml(SimpleXMLElement $xml, $domver = null, $preserveWhitespace = true, $formatOutput = true) {
        // http://stackoverflow.com/questions/1191167/format-output-of-simplexml-asxml
    
        // create new wrapper, so we can get formatting options
        $dom = new DOMDocument($domver);
        $dom->preserveWhiteSpace = $preserveWhitespace;
        $dom->formatOutput = $formatOutput;
        // now import the xml (converted to dom format)
        /*
        $ix = dom_import_simplexml($xml);
        $ix = $dom->importNode($ix, true);
        $dom->appendChild($ix);
        */
        $dom->loadXML($xml->asXML());
    
        // print
        return $dom->saveXML();
    }//--   fn  get_formatted_xml
    
        14
  •  3
  •   karthikr    13 年前

    用这样的话来称呼它

    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;
            }
        }
    
        15
  •  3
  •   caiofior    12 年前

    我发现这个解决方案与原来的问题类似

    <?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();
    
        16
  •  3
  •   Ardi    12 年前

    function arrayToXML(Array $array, SimpleXMLElement &$xml) {
    
        foreach($array as $key => $value) {
    
            // None array
            if (!is_array($value)) {
                (is_numeric($key)) ? $xml->addChild("item$key", $value) : $xml->addChild($key, $value);
                continue;
            }   
    
            // Array
            $xmlChild = (is_numeric($key)) ? $xml->addChild("item$key") : $xml->addChild($key);
            arrayToXML($value, $xmlChild);
        }
    }   
    

    我还为此添加了一个测试类,您可能会发现它很有用:

    class ArrayToXmlTest extends PHPUnit_Framework_TestCase {
    
        public function setUp(){ }
        public function tearDown(){ }
    
        public function testFuncExists() {
            $this->assertTrue(function_exists('arrayToXML'));
        }
    
        public function testFuncReturnsXml() {
            $array = array(
                'name' => 'ardi',
                'last_name' => 'eshghi',
                'age' => 31,
                'tel' => '0785323435'
            );
    
            $xmlEl =  new SimpleXMLElement('<root/>');
            arrayToXml($array, $xmlEl);
    
            $this->assertTrue($xmlEl instanceOf SimpleXMLElement);
        }
    
        public function testAssocArrayToXml() {
    
            $array = array(
                'name' => 'ardi',
                'last_name' => 'eshghi',
                'age' => 31,
                'tel' => '0785323435'
            );
    
            $expectedXmlEl = new SimpleXMLElement('<root/>'); 
            $expectedXmlEl->addChild('name', $array['name']);
            $expectedXmlEl->addChild('last_name', $array['last_name']);
            $expectedXmlEl->addChild('age', $array['age']);
            $expectedXmlEl->addChild('tel', $array['tel']);
    
            $actualXmlEl =  new SimpleXMLElement('<root/>');
            arrayToXml($array, $actualXmlEl);
    
            $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML());
        }
    
        public function testNoneAssocArrayToXml() {
    
            $array = array(
                'ardi',
                'eshghi',
                31,
                '0785323435'
            );
    
            // Expected xml value
            $expectedXmlEl = new SimpleXMLElement('<root/>'); 
            foreach($array as $key => $value)
                $expectedXmlEl->addChild("item$key", $value);
    
            // What the function produces       
            $actualXmlEl =  new SimpleXMLElement('<root/>');
            arrayToXml($array, $actualXmlEl);
    
            $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML());
        }
    
        public function testNestedMixArrayToXml() {
    
            $testArray = array(
                "goal",
                "nice",
                "funny" => array(
                    'name' => 'ardi',
                    'tel'   =>'07415517499',
                    "vary",
                    "fields" => array(
                        'small',
                        'email' => 'ardi.eshghi@gmail.com'
                    ),
    
                    'good old days'
    
                ),
    
                "notes" => "come on lads lets enjoy this",
                "cast" => array(
                    'Tom Cruise',
                    'Thomas Muller' => array('age' => 24)
                )
            );
    
            // Expected xml value
            $expectedXmlEl = new SimpleXMLElement('<root/>'); 
            $expectedXmlEl->addChild('item0', $testArray[0]);
            $expectedXmlEl->addChild('item1', $testArray[1]);
            $childEl = $expectedXmlEl->addChild('funny');
            $childEl->addChild("name", $testArray['funny']['name']);
            $childEl->addChild("tel", $testArray['funny']['tel']);
            $childEl->addChild("item0", "vary");
            $childChildEl = $childEl->addChild("fields");
            $childChildEl->addChild('item0', 'small');
            $childChildEl->addChild('email', $testArray['funny']['fields']['email']);
            $childEl->addChild("item1", 'good old days');
            $expectedXmlEl->addChild('notes', $testArray['notes']);
            $childEl2 = $expectedXmlEl->addChild('cast');
            $childEl2->addChild('item0', 'Tom Cruise');
            $childChildEl2 = $childEl2->addChild('Thomas Muller');
            $childChildEl2->addChild('age', $testArray['cast']['Thomas Muller']['age']);
    
            // What the function produces       
            $actualXmlEl = new SimpleXMLElement('<root/>');
            arrayToXml($testArray, $actualXmlEl);
    
            $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML());
        }
    }      
    
        17
  •  3
  •   Nishad Up    10 年前

    其他解决方案:

    $marray=array(....);
    $options = array(
                    "encoding" => "UTF-8",
                    "output_type" => "xml", 
                    "version" => "simple",
                    "escaping" => array("non-ascii, on-print, markup")
                    );
    $xmlres = xmlrpc_encode_request('root', $marray, $options);
    print($xmlres);
    
        18
  •  3
  •   Mimouni    10 年前

    如果数组是关联的并正确设置了键,那么首先将其转换为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”。

        19
  •  2
  •   frankey    14 年前

    // 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");
                   }
              }
         }
    }
    
        20
  •  1
  •   Toon Krijthe    13 年前

    您可以在代码中直接使用以下函数,

        function artoxml($arr, $i=1,$flag=false){
        $sp = "";
        for($j=0;$j<=$i;$j++){
            $sp.=" ";
         }
        foreach($arr as $key=>$val){
            echo "$sp&lt;".$key."&gt;";
            if($i==1) echo "\n";
            if(is_array($val)){
                if(!$flag){echo"\n";}
                artoxml($val,$i+5);
                echo "$sp&lt;/".$key."&gt;\n";
            }else{
                  echo "$val"."&lt;/".$key."&gt;\n";
             }
        }
    
    }
    

    使用第一个参数作为数组调用函数,第二个参数必须为1,这将增加以实现完美缩进,第三个参数必须为true。

    调用应该是,调用函数应该用 <pre>

      artoxml($array1,1,true);   

        21
  •  1
  •   Andrey    13 年前
    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;
    }
    
        22
  •  1
  •   user2381982    11 年前
    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);
    
        23
  •  1
  •   Daniele Orlando    10 年前

    FluidXML 您可以从 PHP数组 SimpleXML

    $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

        24
  •  0
  •   w35l3y    17 年前

    如果详细的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);
    ?>
    
        25
  •  0
  •   Kamil Dąbrowski    14 年前
    function array2xml($array, $xml = false){
    
        if($xml === false){
    
            $xml = new SimpleXMLElement('<?xml version=\'1.0\' encoding=\'utf-8\'?><'.key($array).'/>');
            $array = $array[key($array)];
    
        }
        foreach($array as $key => $value){
            if(is_array($value)){
                $this->array2xml($value, $xml->addChild($key));
            }else{
                $xml->addChild($key, $value);
            }
        }
        return $xml->asXML();
    }
    
        26
  •  0
  •   Mihai Iorga    14 年前

    我的答案,拼凑其他人的答案。这将纠正无法补偿数字键的错误:

    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() 函数假定数组首先由数字键组成。如果数组具有初始元素,则会删除 foreach() 和 $elem 委员会的发言 数组\u到\u xml() 函数和只传递 $xml 相反

        27
  •  0
  •   Jouni Mäkeläinen    13 年前

    我会对投票数第二高的答案进行评论,因为如果存在数字索引的内部数组,它不会保留结构并生成糟糕的xml。

    我在此基础上开发了自己的版本,因为我需要json和xml之间的简单转换,而不管数据的结构如何。我的版本保留数字键信息和原始数组的结构。它通过将值包装到具有包含数字键的键属性的值命名元素,为数字索引值创建元素。

    例如

    array('test' => array(0 => 'some value', 1 => 'other'))

    <test><value key="0">some value</value><value key="1">other</value></test>

    我的array_to_xml-function版本(希望对某人有所帮助:)

    function array_to_xml($arr, &$xml) {
        foreach($arr as $key => $value) {
            if(is_array($value)) {
                if(!is_numeric($key)){
                    $subnode = $xml->addChild("$key");
                } else {
                    $subnode = $xml->addChild("value");
                    $subnode->addAttribute('key', $key);                    
                }
                array_to_xml($value, $subnode);
            }
            else {
                if (is_numeric($key)) {
                    $xml->addChild("value", $value)->addAttribute('key', $key);
                } else {
                    $xml->addChild("$key",$value);
                }
            }
        }
    }   
    
        28
  •  0
  •   ace    13 年前

    整个XML结构在$data数组中定义:

    function array2Xml($data, $xml = null)
    {
        if (is_null($xml)) {
            $xml = simplexml_load_string('<' . key($data) . '/>');
            $data = current($data);
            $return = true;
        }
        if (is_array($data)) {
            foreach ($data as $name => $value) {
                array2Xml($value, is_numeric($name) ? $xml : $xml->addChild($name));
            }
        } else {
            $xml->{0} = $data;
        }
        if (!empty($return)) {
            return $xml->asXML();
        }
    }
    
        29
  •  0
  •   Bharat Chodvadiya    13 年前

    如果您在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'
        ),
    );
    

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

        30
  •  0
  •   Francisco Luz    12 年前

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