कैसे सरणी को SimpleXML में परिवर्तित करें


जवाबों:


209

एक छोटा एक:

<?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 से पहले ठीक कर सकते हैं । array_walk_recursivePHP 5 की आवश्यकता है। आप array_walkइसके बजाय उपयोग कर सकते हैं , लेकिन आप 'stack' => 'overflow'तब xml में नहीं मिलेंगे ।


53
यह काम नहीं करेगा यदि $ test_array में 'other_array' की तरह 'more_another_array' है, क्योंकि कुंजी 'other_array' परिवर्तित नहीं है। इसलिए आपके पास कई '<ओवरफ्लो> स्टैक </ ओवरफ्लो>' होंगे।
समझें

11
यह array_flipकाम नहीं करेगा क्योंकि यह एरेज़ को फ्लिप नहीं कर सकता (जैसे another_arrayमुख्य सरणी के अंदर)।
परत

14
"अन्य_अरे" xml तत्व कहां है? सब कुछ नीचे समतल है :(
FMaz008

2
जब मैंने array_walk_recursive से पहले array_flip जोड़ा तो बहुत अच्छा काम किया। धन्यवाद।
माइक पर्ससेल

12
डाउनवोटिंग क्योंकि array_flipकेवल काम करता है अगर सरणी में कोई समान मान नहीं हैं।
मार्टिज़न

386

यहाँ 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इस स्निपेट में उपयोग किए गए दस्तावेज़


40
यह, IMO, स्वीकृत उत्तर की तुलना में बहुत बेहतर समाधान है। हालाँकि, यह सीमा है कि संख्यात्मक रूप से बंद सरणियों के साथ, यह विकृत XML उत्पन्न करता है। <0> <1> <2> मान्य नोड नाम नहीं हैं।
KOGI

2
हालाँकि, अगर आपके संख्यात्मक रूप से बंद सरणी में केवल एक और सरणी है, जो संख्यात्मक रूप से बंद नहीं है, तो यह नहीं होगा।
ब्रायन पेटी

15
@KOGI मैंने हनमंत उत्तर को संशोधित किया है। अब इसका समर्थन बहुस्तरीय सरणियों है। pastebin.com/pYuXQWee
Mifas

1
यह उदाहरण htmlspecialchars का उपयोग करके तत्व पाठ डेटा में स्पष्ट रूप से विशेष वर्णों से बच जाता है, लेकिन SimpleXMLElement :: addChild अपने वर्ण संस्थाओं में xml विशेष वर्णों का स्वचालित रूप से अनुवाद करता है ताकि htmlspecialchars को छोड़ा जा सके। दिलचस्प बात यह है कि इससे डेटा दोगुना होने का अनुमान नहीं है।
mbaynton

3
@ एलेक्स, आपका संपादन # 5 उदाहरण को विफल बनाता है। यह प्रत्येक आइटम से पहले <item $ x> सम्मिलित करता है, XML आउटपुट को रिकॉर्ड करता है जो लेखक का इरादा नहीं है। हो सकता है कि आप जिस समस्या को ठीक करने का प्रयास कर रहे हैं उसका एक उदाहरण प्रदान करें और हम दोनों मामलों के लिए एक और समाधान पा सकते हैं। इससे पहले कि मैं महसूस करता कि लेखक कोड संशोधित किया गया था।
निकोलस ब्लासजेन

124

यहां दिए गए जवाब केवल नोड्स के साथ एक्सएमएल में सरणी कन्वर्ट करते हैं, आप विशेषताओं को सेट करने में सक्षम नहीं हैं। मैंने एक php फ़ंक्शन लिखा है जो आपको सरणी को php में बदलने की अनुमति देता है और xml में विशेष नोड्स के लिए विशेषता भी सेट करता है। यहाँ नकारात्मक पक्ष यह है कि आपको कुछ सम्मेलनों के साथ एक विशेष तरीके से एक सरणी का निर्माण करना होगा (केवल यदि आप विशेषताओं का उपयोग करना चाहते हैं)

निम्न उदाहरण आपको एक्सएमएल में भी विशेषता सेट करने की अनुमति देगा।

स्रोत यहाँ पाया जा सकता है: https://github.com/digiticket/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>
*/
?>

9
मुझे इस बात का मलाल है कि किसी ने भी इस पर कोई प्रतिक्रिया नहीं दी। यह वर्ग वास्तव में उपयोगी है क्योंकि यह इसके विपरीत कर रहा है जो simpleXMLElement उत्पन्न करेगा। तो यह आपको SimpleXMLElement दोनों तरीकों का उपयोग करने की संभावना देता है।
FMaz008

4
मैं इसे वर्तमान के बजाय उत्तर के रूप में चिह्नित करूंगा। वर्तमान उत्तर पुनरावर्ती सरणियों का निर्माण नहीं
ऑलेक्ज़ेंडर IY

2
अच्छा वर्ग है। मैं लाइन 128 बदल if(!is_array($arr)) {करने के लिए if(!is_array($arr) && $arr !== '') {इतना है कि यह रिक्त स्ट्रिंग के लिए एक नया पाठ नोड संलग्न नहीं होंगे और इसलिए आशुलिपि खाली टैग प्रारूप रहता है यानी 'tag'=>''है <tag/>बजाय<tag></tag>
user1433150

यह अब तक का सबसे अच्छा जवाब है। इसके अलावा इसमें एक ही कुंजी के साथ कई वस्तुओं की सही संरचना है: 1 नोड नाम की कुंजी है, फिर इसमें संख्यात्मक कुंजियों के साथ सरणी होती है। (हनमंत उत्तर के विपरीत)
वासिल पोपोव

1
लेखक @Legionar से एक GitHub मिले github.com/digitickets/lalit/blob/master/src/Array2XML.php
डेरिल टेओ

57

मुझे बहुत सारे कोड का उपयोग करने के सभी उत्तर मिले। यहाँ यह करने के लिए एक आसान तरीका है:

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 == (int) $key) {
                $key = "key_$key";
            }

            $object->addChild($key, $value);
        }   
    }   
}   

फिर यह फ़ंक्शन में सरणी भेजने का एक साधारण मामला है, जो पुनरावृत्ति का उपयोग करता है, इसलिए यह एक बहु-आयामी सरणी को संभाल लेगा:

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

अब $ xml में आपके सरणी के आधार पर एक सुंदर XML ऑब्जेक्ट है जिसमें आपने इसे लिखा है।

print $xml->asXML();

9
मुझे यह समाधान सबसे ज्यादा पसंद है। हालाँकि, संख्यात्मक कुंजियों पर एक परीक्षण जोड़ना अच्छा होगा, जैसे if ( is_numeric( $key ) ) $key = "numeric_$key"; :।
WOUT

@ अच्छा पकड़। जोड़ा गया। मैंने is_numeric के बजाय एक int कास्ट चेक किया क्योंकि is_numeric कुछ दे सकता है, हालाँकि तकनीकी रूप से अपेक्षित है, परिणाम जो वास्तव में आपको फेंक देंगे।
फ्रांसिस लुईस

मैं इस फ़ंक्शन का उपयोग करता हूं, लेकिन $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><rootTag/>');मान्य UTF-8 एन्कोडिंग के लिए बदल दिया गया है ।
दंताजे

मैं इस समाधान की तरह सबसे रूप में अच्छी तरह, सरल करता है यह :-) एक टिप्पणी: आप बदल सकते हैं $object->addChild($key, $value);करने के लिए $object->addChild($key, htmlspecialchars($value));वह असफल से रोकने के लिए जब $ मूल्य की तरह "और" कि जरूरत एक्सएमएल एन्कोडिंग वर्ण हैं।
leo

38
<? Php
समारोह array_to_xml (सरणी $ गिरफ्तार, SimpleXMLElement $ xml)
{
    foreach ($ के रूप में $ गिरफ्तार => $ v) {
        is_array (V $)
            ? array_to_xml ($ v, $ xml-> addChild ($ k))
            : $ xml-> addChild ($ k, $ v);
    }
    वापसी $ xml;
}

$ test_array = सरणी (
    'bla' => 'blub',
    'फू' => 'बार',
    'एक और_अरे' => सरणी (
        'स्टैक' => 'अतिप्रवाह',
    ),
);

गूंज array_to_xml ($ test_array, नया SimpleXMLElement ('<root />')) -> asXML ();

1
यह तब विफल होता है जब आपके सरणी में संख्यात्मक अनुक्रमित के साथ एक आंतरिक सरणी होती है। <0> ... </ 0> मान्य XML नहीं है।
एड्रियानो वरोली पियाजा

@ AdrianoVaroliPiazza बस कुछ $k = (is_numeric($k)) ? 'item' : $k;अंदर की तरह जोड़foreach()
AlienWebguy

यदि सरणी में किसी एक कुंजी का नाम "बॉडी" है, तो यह काम नहीं करता है - अधिक सटीक रूप से, कुंजी को अनदेखा किया जाता है और ट्रेस किया जाता है। यह पता लगाने की कोशिश क्यों की जा रही है।
बंबाक्स

@ बम्बैक्स एकमात्र कारण है जिसके बारे में मैं सोच सकता हूं कि क्या XML को कुछ बाद के बिंदु पर HTML के रूप में पार्स किया जा रहा है।
ब्रिलिएंड

16

PHP 5.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();
}

यह चयनित उत्तर से एक सीधी प्रतिलिपि की तरह लगता है, बस एक फ़ंक्शन में डाल दिया जाता है।
फेजेस्ट

मैं AddChild भाग में htmlspecialchars () जोड़ूँगा, इस तरह: $ xml-> addChild ($ key, htmlspecialchars ($ value));
Tyreal

15

एक और सुधार:

/**
* 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');

धन्यवाद! आपका फ़ंक्शन किसी भी n- आयामी सरणी की सटीक सामग्री देता है।
besciualex

12

यहाँ मेरी प्रविष्टि, सरल और साफ है ..

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

8

तो वैसे भी ... मैंने onokazu का कोड लिया (धन्यवाद!) और XML में बार-बार टैग होने की क्षमता को जोड़ा, यह विशेषताओं का भी समर्थन करता है, आशा है कि कोई इसे उपयोगी पाता है!

 <?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();
    ?>

कोड को स्पष्ट करने के लिए अपने परिवर्तनों पर टिप्पणी करने में मददगार हो सकता है; अभी भी, अच्छा इसके अलावा
स्ट्रोमहॉक

इसने मेरे लिए WP ऑल एक्सपोर्ट के साथ काम किया। मुझे is_numeric भाग को थोड़ा बदलना पड़ा: if (is_numeric($k)) { $i = $k + 1; $child = $xml->addChild("_$i"); array_to_xml($v, $child); }
achiever

4

मैं कुछ कार्यों का उपयोग करता हूं, जिन्हें मैंने PHP और jQuery आदि से आगे और पीछे पारित करने के लिए xml उत्पन्न करने के लिए कुछ समय पहले लिखा था ... न तो किसी भी अतिरिक्त फ्रेमवर्क का उपयोग करें केवल शुद्ध रूप से एक स्ट्रिंग उत्पन्न करता है जिसे तब SimpleXML (या अन्य ढांचे) के साथ उपयोग किया जा सकता है ) ...

अगर यह किसी के लिए उपयोगी है, तो कृपया इसका उपयोग करें :)

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

सब के लिए प्यार :)


4

मुझे एक कोड चाहिए था जो सभी तत्वों को एक सरणी के अंदर ले जाएगा और उन्हें विशेषताओं के रूप में और उप-तत्वों के रूप में सभी सरणियों का इलाज करेगा।

तो जैसे कुछ के लिए

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

आप सरणी की लंबाई के लिए चेक जोड़ना चाह सकते हैं ताकि कुछ तत्व डेटा भाग के अंदर सेट हो जाएं और एक विशेषता के रूप में नहीं।


4

यहां सब कुछ के आधार पर, उपसर्ग के माध्यम से संख्यात्मक सूचकांक + विशेषताओं को संभालता है @और मौजूदा नोड्स में 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>

बोनस: फ़ॉर्मेटिंग एक्सएमएल

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

एक अद्यतन संस्करण जो संख्यात्मक टैग के बजाय बाल तत्वों के रूप में दोहराता है: github.com/zaus/forms-3rdparty-xpost/blob/…
drzaus

3

यहाँ एक समारोह है कि मेरे लिए चाल है:

बस इसे कुछ के साथ कहते हैं

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

3

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

3

मुझे यह समस्या मूल समस्या के समान लगी

<?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();

3

उपर्युक्त अधिकांश उत्तर सही हैं। हालाँकि, मैं इस उत्तर के साथ आया था जो array_walk_recursive संगतता समस्या को हल करता है और संख्यात्मक कुंजियों की समस्या को भी हल करता है। इसने मेरे द्वारा किए गए सभी परीक्षणों को भी पास किया:

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

3

अन्य समाधान:

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

इसमें RPC- स्टाइल XML बनाने का अप्रत्याशित प्रभाव है जैसे कि methodCall, methodName, scalars और vectors आदि जैसे सामान। यह वास्तव में XML में किसी सरणी को सीधे अर्थ में परिवर्तित नहीं कर रहा है।
वोलोमाइक

3

यदि सरणी साहचर्य और सही ढंग से कुंजीबद्ध है, तो संभवत: इसे पहले 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" का उपयोग करें।

मैं कोशिश करूँगा कि बाद में और इस पोस्ट को दोनों संस्करणों के साथ अपडेट करूँ।


उस बिट जहां मैंने "<array> </ array>" का उल्लेख किया है, मुझे एहसास हुआ कि स्ट्रिंग संस्करण को कुछ इसी तरह की आवश्यकता है। मूल रूप से सरणी में बहुत बाहर की तरफ एक नोड होना चाहिए। मुझे पूरी बात पर सोने दो, मेरे पास कुछ ऐसा होगा जो उस प्रारंभिक त्रुटि को तुरंत पकड़ लेता है।
एंथनी

2

उपरोक्त फ़ंक्शन पर बस संपादित करें, जब एक कुंजी संख्यात्मक होती है, तो एक उपसर्ग जोड़ें "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");
               }
          }
     }
}

1

आप निम्नलिखित फ़ंक्शन का उपयोग सीधे कोड में कर सकते हैं,

    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 होना चाहिए, यह पूर्ण इंडेंटेशन के लिए बढ़ाया जाएगा, और तीसरा सही होना चाहिए।

उदाहरण के लिए, यदि सरणी चर को परिवर्तित किया जाना है $ array1 तो, कॉलिंग होगी, कॉलिंग फ़ंक्शन को <pre>टैग के साथ एन्क्रिप्ट किया जाना चाहिए ।

  artoxml ($ array1,1, सच);   

कृपया फ़ाइल को निष्पादित करने के बाद पृष्ठ स्रोत देखें, क्योंकि <और> प्रतीकों को HTML पृष्ठ में प्रदर्शित नहीं किया जाएगा।


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

यह DOMDocument xml बनाने के लिए उत्कृष्ट विकल्प है। धन्यवाद @Andrey
altsyset

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

या यदि आप एस के साथ समाप्त होने वाले अपरा के साथ काम कर रहे हैं:

$key = is_string($key) ? $key : preg_replace('/s$/', '', $oldNodeName);

1

FluidXML के साथ , आप एक PHP ऐरे से शुरू कर सकते हैं, सिम्पलेक्स के लिए एक 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


0

यदि वर्बोज़ xml कोई समस्या नहीं है, तो आप सरणी से xml बनाने के लिए xmlrpc_encode का उपयोग कर सकते हैं। 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);
?>

यह फ़ंक्शन असमर्थित है और वास्तव में, PHP 5.2.16 या PHP 5.3.5 के मेरे निर्माण में प्रदान नहीं किया गया है। (रिटर्न "PHP घातक त्रुटि: अपरिभाषित समारोह को कॉल करें xmlrpc_encode ()")
danorton

आपको php.ini में निम्नलिखित लाइन को अनइंस्टॉल करना है: एक्सटेंशन = php_xmlrpc.dll
w35l3y

@ w35l3y मैंने अपना आईएन चेक किया। इसमें वह एक्सटेंशन भी नहीं है और मैं v 5.3.6 का उपयोग कर रहा हूं।
माइक एस

0
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();
}

0

मेरा जवाब, दूसरों के जवाब को एक साथ मिलाना। यह संख्यात्मक कुंजियों की भरपाई करने में विफलता के लिए सही होना चाहिए:

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से बयान array_to_xml()समारोह और बस पारित $xmlबजाय।


0

मैंने दूसरे सबसे अधिक वोट किए गए उत्तर पर टिप्पणी की होगी, क्योंकि यह संरचना को संरक्षित नहीं करता है और यदि खराब रूप से अनुक्रमित आंतरिक सरणियों में खराब एक्सएमएल उत्पन्न करता है।

मैंने इसके आधार पर अपना खुद का संस्करण विकसित किया, क्योंकि मुझे डेटा की संरचना की परवाह किए बिना 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);
            }
        }
    }
}   

0

संपूर्ण XML संरचना को $ डेटा में परिभाषित किया गया है:

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

यदि आप 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'
    ),
);

फिर यह साहचर्य सरणी को xml स्वरूप में परिवर्तित करने के लिए सबसे अच्छा है। इस कोड को कंट्रोलर फाइल में देखें।

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

मुझे उम्मीद है कि यह सभी को मदद करेगा।


0

// 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);
    }
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.