Home > Back-end >  adding node in xml file via php
adding node in xml file via php

Time:12-06

I have a php array and I need to convert it into xml file but I cant get the format I want.

Array:

Array
(
    [1] => Array
        (
            [2000307] => Array
                (
                    [eventid] => 2000307
                    [eveseq] => 100
                    [fee] => 200
                )

            [2000310] => Array
                (
                    [eventid] => 2000310
                    [eveseq] =>101
                    [fee] => 300
                )

        )

)

convert array to xml:

$xml = new SimpleXMLElement('<Event/>');
event_to_xm($array, $xml);

function event_to_xml($array, &$xml) {
        $array = json_decode($array,TRUE);
        foreach($array as $key => $value) {
            foreach($value as $id => $index) {
                foreach($index as $title => $result) {
                    if(is_array($result)) {
                        if(!is_numeric($title)){
                            $subnode = $xml->addChild($title);
                            array_to_xml($result, $xml);
                        } else {
                            array_to_xml($result, $xml);
                        }
                    } else {
                        $xml->addChild($title,  htmlspecialchars($result));
                    }
                }
            }
        }
    }

event.xml:

<?xml version="1.0"?>
<Event>
  <eventid>2000307</eventid>
  <eveseq>100</eveseq>
  <fee>zz</fee>
  <eventid>2000310</eventid>
  <eveseq>101</eveseq>
  <fee>0</fee>
</Event>

What I expect is that it will create a cd tag when a new array begin:

xml:

<?xml version="1.0"?>
<Event>
 <cd>
  <eventid>2000307</eventid>
  <eveseq>100</eveseq>
  <fee>200</fee>
</cd>
<cd>
  <eventid>2000310</eventid>
  <eveseq>101</eveseq>
  <fee>300</fee>
</cd>
</Event>

What I tried: I tried to direct add a attribute but I encounter this error Call to a member function addChild() on null

$xml=new SimpleXMLElement("event.xml", 0, TRUE);
$child = $xml->event[0]->addChild("cd");

CodePudding user response:

I would take a somewhat different approach - first, use DOMDocument instead of SimpleXML, and, second, use xpath and a fragment to insert elements into the document. Something like this:

$events = array(
    "2000307" => array(
        "eventid" => 2000307,
        "eveseq" => 100,
        "fee" => 200,
    ),
    "2000310" => array(         
        "eventid" => 20003010,
        "eveseq" => 101,
        "fee" => 300,
    )
);
#create a blank document with a root element
$xml = <<<'XML'
<?xml version="1.0"?>
<Event></Event>
XML;

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);

$expr = "//Event";
#indicate where to insert the new elements
$dest = $xpath->query($expr);

foreach($events as $event) {
   $fragment = $document->createDocumentFragment();
   #this is the new element to be inserted
   $instance = "  <cd>
    <eventid>{$event['eventid']}</eventid>
    <eveseq>{$event['eveseq']}</eveseq>
    <fee>{$event['fee']}</fee>
  </cd>\n";
  $fragment->appendXML($instance);
  $dest[0]->appendChild($fragment);
}

$document->formatOutput = TRUE;
echo $document->saveXML();

Output should be your expected output.

CodePudding user response:

You can iterate array data and construct new simplexml object with new 'cd' child. Try like this:

$data = array (
  "2000307" => array(
     "eventid" => 2000307,
     "eveseq" => 100,
     "fee" => 200,
   ),
  "2000310" => array(
     "eventid" => 20003010,
     "eveseq" => 101,
     "fee" => 300,
   )
);

function to_xml(SimpleXMLElement $object, array $data)
{
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $new_object = $object->addChild('cd');
            to_xml($new_object, $value);
        } else {
            $object->addChild($key, $value);
        } 
     }
}

$xml = new SimpleXMLElement('<event/>');
to_xml($xml, $data);
print $xml->asXML();
  • Related