0

I have a simple XML string:

$sample = new SimpleXMLElement('<root><parent><child1></child1></parent></root>');

and i try to find node with xpath() and add child to this node.

$node = $sample->xpath('//parent');
$node[0]->addChild('child2');
echo $sample->asXML();

As you see child2 is added as a child of child1, not as a child of parent.

<root>
  <parent>
    <child1>
      <child2></child2>
    </child1>
  </parent>
</root>

But if i change my XML, addChild() works great. This code

$sample = new SimpleXMLElement('<root><parent><child1><foobar></foobar></child1></parent></root>');
$node = $sample->xpath('//parent');
$node[0]->addChild('child2');
echo $sample->asXML();

returns

<root>
  <parent>
    <child1>
      <foobar></foobar>
    </child1>
    <child2>
    </child2>
  </parent>
</root>

So i have two questions:

  1. Why?
  2. How can i add child2 as a child of parent, if child1 has no child?
hakre
  • 193,403
  • 52
  • 435
  • 836
Andrew Roo
  • 61
  • 1
  • 2
  • 5
  • 1
    What version of PHP and libxml2 are you using? Your "broken" code [works for me](http://3v4l.org/JiGAf#v513). – salathe Apr 05 '13 at 20:26
  • 1
    In that case, the link I gave shows your code working fine for 2.7.8 on 5.4.0. – salathe Apr 05 '13 at 22:41
  • I can only underline what salathe already wrote: The code as-is in your question does just work. I also can not imagine why that happens to you. You might want to debug first before adding the child, e.g.: `var_dump($node[0]->asXML());`. – hakre Apr 08 '13 at 11:54

1 Answers1

0

xpath() returns the CHILDREN of the element passed to it. So, when you addChild() to the first element xpath() returns, you are actually adding a child to the first element of parent, which is child1. When you run this code, yo uwill see that is is creating a "parentChild" element as a child of "parent" -

<?php
$original = new SimpleXMLElement('<root><parent><child1></child1></parent></root>');
$root = new SimpleXMLElement('<root><parent><child1></child1></parent></root>');
$parent = new SimpleXMLElement('<root><parent><child1></child1></parent></root>');
$child1 = new SimpleXMLElement('<root><parent><child1></child1></parent></root>');
$tXml = $original->asXML();
printf("tXML=[%s]\n",$tXml);
$rootChild = $root->xpath('//root');
$rootChild[0]->addChild('rootChild');
$tXml = $root->asXML();
printf("node[0]=[%s] tXML=[%s]\n",$rootChild[0],$tXml);
$parentChild = $parent->xpath('//parent');
$parentChild[0]->addChild('parentChild');
$tXml = $parent->asXML();
printf("node[0]=[%s] tXML=[%s]\n",$parentChild[0],$tXml);
$child1Child = $child1->xpath('//child1');
$child1Child[0]->addChild('child1Child');
$tXml = $child1->asXML();
printf("node[0]=[%s] tXML=[%s]\n",$child1Child[0],$tXml);
?>

tXML=[<?xml version="1.0"?>
<root><parent><child1/></parent></root>]
tXML=[<?xml version="1.0"?>
<root><parent><child1/></parent><rootChild/></root>]
tXML=[<?xml version="1.0"?>
<root><parent><child1/><parentChild/></parent></root>]
tXML=[<?xml version="1.0"?>
<root><parent><child1><child1Child/></child1></parent></root>]
Mark
  • 13
  • 1
  • 6