user1433150
user1433150

Reputation: 319

both appendChild and insertBefore when called on DOMDocument append node after root

I have a function to add a valueless element and a bunch of child elements with values to an xml file, so I wrote it to take two arguments $tag(String the parent node) and $hash(Array $elm=>$elm_value)

function addUser($tag, $hash)
    {
        $dom = new DOMDocuemnt();
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->load('file');

        $parent = $dom->createElement($tag);
        foreach($hash as $elm => $value){
            $n = $dom->createElement($elm, $value);
            $parent->appendChild($n);
        }
        $dom->appendChild($parent);

        $dom->save('file');
        return $dom->saveXML();
    }

Only problem is $dom->appendChild($parent) appends everything after the root element's closing tag, mucking up my xml file. So I tried $dom->insertBefore($parent) with the same result. So instead I tried $xpath = new DOMXPath($dom); $root = $xpath->query('/')->item(0); $root->appendChild($parent);. Same result. Then I tried selecting the root element with $dom->getElementsByTagName(name of root)->item(0); And was surprised when that actually worked! But what if I don't know the tag name? Is there another way to select the root element so that calling appendChild or inserBefore will add the element before the root closing tag instead of after it?

Upvotes: 2

Views: 2821

Answers (1)

web-nomad
web-nomad

Reputation: 6003

This seems to work:

Initial XML file -

<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <node Id="1">
        <Clicks>click1</Clicks>
    </node>
</root>

PHP -

<?php

function addUser($tag, $hash) {
    $dom = new DOMDocument('1.0');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->load('test.xml');

    $parent = $dom->createElement($tag);
    $dom->documentElement->appendChild($parent);
    foreach($hash as $elm => $value){
        $n = $dom->createElement($elm);
        $n->appendChild( $dom->createTextNode( $value ) );
        $parent->appendChild($n);
    }

    $dom->save('test.xml');
}

$arr = array( 'name' => 'pushpesh', 'age' => 30, 'profession' => 'SO bugger' );
addUser('user', $arr);

XML file is now -

<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node Id="1">
    <Clicks>click1</Clicks>
  </node>
  <user>
    <name>pushpesh</name>
    <age>30</age>
    <profession>SO bugger</profession>
  </user>
</root>

Hope this helps.

Upvotes: 3

Related Questions