Wais Kamal
Wais Kamal

Reputation: 6180

XML child element does not get added but does not throw any errors

Following up from my previous question.

I am using addChild() to add another <comment> element as a child of the root element. I used the code from this question:

$file = "comments.xml";

$comment = $xml -> comment;

$comment -> addChild("user","User2245");
$comment -> addChild("date","02.10.2018");
$comment -> addChild("text","The comment text goes here");

$xml -> asXML($file)

Now, when I echo the file contents:

foreach($xml -> children() as $comments) { 
  echo $comments -> user . ", "; 
  echo $comments -> date . ", "; 
  echo $comments -> text . "<br>";
}

I only get the old file contents (with no changes):

User4251,02.10.2018,Comment body goes here
User8650,02.10.2018,Comment body goes here

I am using the same comments.xml file. There are no errors displayed.

Why doesn't the child element get appended?

Upvotes: 2

Views: 63

Answers (2)

IMSoP
IMSoP

Reputation: 97688

If you output the full XML, with echo $xml->asXML(), you will see that, as you requested, additional child nodes have been added to the first comment node:

<comment>
    <user>User4251</user>
    <date>02.10.2018</date> 
    <text>Comment body goes here</text> 
    <user>User2245</user><date>02.10.2018</date><text>The comment text goes here</text>
</comment>

The reason only the first comment has been changed is the same reason that your echo doesn't show the new values: if you reference an element like $xml->comment or $comment->user, you get the first child element with that name; it's just short-hand for $xml->comment[0] or $comment->user[0]. This is actually really handy for navigating through XML documents, because you don't have to know whether there's one or several elements with a particular name, you can write $xml->comment->user or $xml->comment[0]->user[0] or $xml->comment->user[0] and so on.

Since you called addChild, the new user, date, and text aren't the first children with that name, so they don't show up in your output.

If what you wanted was to create a new comment, you would need to add that first:

$comment = $xml->addChild('comment');
$comment->addChild('user', 'User2245');

If what you wanted was to change the values of the child elements, you can just write to them instead of adding a new child:

$comment = $xml->comment[0]; // or just $comment = $xml->comment;
$comment->user = 'User2245';

Or you could add something to each of the existing comments (note that here we use $xml->comment as though it was an array; again, SimpleXML will let us do this whether there's one or several matching elements):

foreach ( $xml->comment as $comment ) {
    $comment->addChild('modified', 'true');
}

Upvotes: 1

user3783243
user3783243

Reputation: 5224

You are adding to one of the comment elements, add it to the full doc.

$xml = new simplexmlelement('<?xml version="1.0" encoding="utf-8"?>
<comments><comment>
  <user>User4251</user>
  <date>02.10.2018</date>
  <text>Comment body goes here</text>
</comment>
<comment>
  <user>User8650</user>
  <date>01.10.2018</date>
  <text>Comment body goes here</text>
</comment></comments>');
$child = $xml->addchild('comment');
$child->addChild("user","User2245");
$child->addChild("date","02.10.2018");
$child->addChild("text","The comment text goes here");
echo $xml->asXML();

https://3v4l.org/Pln6U

Upvotes: 1

Related Questions