How to convert array to SimpleXML

前端 未结 30 2562
遇见更好的自我
遇见更好的自我 2020-11-21 06:52

How can I convert an array to a SimpleXML object in PHP?

相关标签:
30条回答
  • 2020-11-21 07:23

    With FluidXML you can generate, starting from a PHP Array, an XML for SimpleXML with... just two lines of code.

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

    An example array could be

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

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

    0 讨论(0)
  • 2020-11-21 07:23

    Whole XML structure is defined in $data Array:

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:26

    Here is my entry, simple and clean..

    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);
    
    0 讨论(0)
  • 2020-11-21 07:28

    Based on everything else here, handles numerical indices + attributes via prefixing with @, and could inject xml to existing nodes:

    Code

    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
    

    Usage

    // 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
    

    Result

    <?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>
    

    Bonus: Formatting 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
    
    0 讨论(0)
  • 2020-11-21 07:28

    You can Use the following function in you code directly,

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

    Call the function with first argument as your array and the second argument must be 1, this will be increased for perfect indentation, and third must be true.

    for example, if the array variable to be converted is $array1 then, calling would be, the calling function should be encapsulated with <pre> tag.

      artoxml($array1,1,true);   

    Please see the page source after executing the file, because the < and > symbols won't be displayed in a html page.

    0 讨论(0)
  • 2020-11-21 07:29
    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;
    }
    

    This function returns for example a list of <obj>...</obj><obj>...</obj> XML tags for numeric indexes.

    Input:

        array(
        'people' => array(
            'dog',
            'cat',
            'life' => array(
                'gum',
                'shoe',
            ),
            'fish',
        ),
        array('yeah'),
    )
    

    Output:

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

    This should satisfy all common needs. Maybe you may change the 3rd line to:

    $key = is_string($key) ? $key : $oldNodeName . '_' . $key;
    

    or if you are working with plurals ending with s:

    $key = is_string($key) ? $key : preg_replace('/s$/', '', $oldNodeName);
    
    0 讨论(0)
提交回复
热议问题