3

I have this array

array(2) {
  [0] =>
  array(3) {
    ['name'] => string(4) "John"
    ['lastname'] => string(3) "Don"
    ['pesel'] => string(6) "987987"
  }
  [1] =>
  array(3) {
    ['name'] => string(4) "Mike"
    ['lastname'] => string(5) "Evans"
    ['pesel'] => string(5) "89779"
  }
}

And I want create a xml file from array above, I use this code to create a xml file

$student_info = array($resultant_array);

// 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_info,$xml_student_info);

//saving generated xml file
$xml_student_info->asXML('inxfo.xml');



// function defination to convert array to xml
function array_to_xml($student_info, $xml_student_info) {
    foreach($student_info as $key => $value) {
            var_dump($value);
            echo '<br />';
        if(is_array($value)) {


            if(!is_numeric($key)){

                $subnode = $xml_student_info->addChild("$key");
                array_to_xml($value, $subnode);

            }
            else{

                array_to_xml($value, $xml_student_info);
            }
        }
        else { 

            $xml_student_info->addChild("$key","$value");

        }
    }
}

This code give mi solution like this

<student_info>
  <name>John</name>
  <lastname>Dozzn</lastname>
  <pesel>987987</pesel>
  <nme>Mike</name>
  <lastname>Evans</lastname>
  <pesel>89779</pesel>
</student_info>

But I want result like this

 <student_info>
      <person>
         <name>John</name>
         <lastname>Dozzn</lastname>
         <pesel>987987</pesel>   
      </person>
      <person>
         <name>Mike</name>         
         <lastname>Evans</lastname>
         <pesel>89779</pesel>
    </person>
 </student_info>

How can I add additional child to my xml code ?

2

2 Answers 2

3

In your case, change the else part:

if(!is_numeric($key)){
     $subnode = $xml_student_info->addChild("$key");
     array_to_xml($value, $subnode);
}
else{
     $subnode = $xml_student_info->addChild("person");
     array_to_xml($value, $subnode);
}

But as Andrej suggested, you probably want to look at more general functions.

EDIT: My version that works:

$student_info = array(
    array(
        'name' => "John",
        'lastname' => "Don",
        'pesel' => "987987",
    ),
    array(
        'name' => "Mike",
        'lastname' => "Evans",
        'pesel' => "89779",
    )
);

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

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("person");
                array_to_xml($value, $subnode);
            }
        }
        else { 
            $xml_student_info->addChild("$key","$value");
        }
    }
}

array_to_xml($student_info, $xml_student_info);

var_dump( $xml_student_info->asXML() );

Outputs:

string '<?xml version="1.0"?>
<student_info><person><name>John</name><lastname>Don</lastname><pesel>987987</pesel></person><person><name>Mike</name><lastname>Evans</lastname><pesel>89779</pesel></person></student_info>

' (length=211)

Sign up to request clarification or add additional context in comments.

3 Comments

I tried something like this but I get this result <student_info><person/><person/><name>John</name>
I think I'll need to see your edited code. I tried the edit and it worked (see edit).
Thank you! I searched hi and low for something like this before settling with writing my own code using array_walk and others. After a few hours, although i had something mostly working, there was still too many things to fix. Whatever my next search term was it led me to this which worked within 30 mins of applying it to my needs! Much appreciated. I posted another answer with a slightly modified version for generalization of the code.
0

To contribute to this answer by Scott Yang I edited their code to allow for generalization of the subnode name instead of the currently hardcoded option.

// Recursive looping of nested array into xml object using SimpleXMLElement
function buildXml($array, $toXml, $subnodeName = null) {
    foreach($array as $key => $value) {
            if(is_array($value)) {
                    if(!is_numeric($key)){
                            // remove the last char from the string
                            // presumably removing the trailing `s` and converting from plural to single
                            // can be replaced with a more robust conversion if necessary
                            $subnodeName = substr($key, 0, -1);
                            $subnode = $toXml->addChild("$key");
                            buildXml($value, $subnode, $subnodeName);
                    }
                    else{
                            $subnode = $toXml->addChild("$subnodeName");
                            buildXml($value, $subnode);
                    }
            }
            else {
                $toXml->addChild("$key","$value");
            }
        }
}

$toXml = new SimpleXMLElement('<root/>'); // init the xml object
buildXml($data_array, $toXml); // walk the array and build xml object
$xmlOutput = $toXml->asXML(); // convert to string
print_r($xmlOutput);

Now with an array such as

$data_array = array(
    'users' => array (
        array(
            'name' => "John",
            'lastname' => "Doe",
            'artworks' => array (
                array (
                    'title' => 'Artwork 1',
                    'filename' => 'artwork1.jpg',
                ),
                array (
                    'title' => 'Artwork 2',
                    'filename' => 'artwork2.jpg',
                )
            )
        ),
        array(
            'name' => "Jane",
            'lastname' => "Smith",
            'colors' => array (
                array ('name' => 'green'),
                array ('name' => 'yellow'),
            )
        )
    )
);

the xml output would be

<?xml version="1.0"?>
<root>
    <users>
        <user>
            <name>John</name>
            <lastname>Doe</lastname>
            <artworks>
                <artwork>
                    <title>Artwork 1</title>
                    <filename>artwork1.jpg</filename>
                </artwork>
                <artwork>
                    <title>Artwork 2</title>
                    <filename>artwork2.jpg</filename>
                </artwork>
            </artworks>
        </user>
        <user>
            <name>Jane</name>
            <lastname>Smith</lastname>
            <colors>
                <color>
                    <name>green</name>
                </color>
                <color>
                    <name>yellow</name>
                </color>
            </colors>
        </user>
    </users>
</root>

Of course, this is a simple assumption of s being tacked on to the end of a word to make it plural. This won't work with geese being the keyname where the subnode name should be goose.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.