Search code examples
phpxmlsimplexmlupdatexml

How can I update children, grouped with id "X", using simpleXML


I am new to simplexml so forgive me if I get some terms mixed up :)

I have the following xml file stored at: js/data.xml:

<users>
  <user>
    <id>2011</id>
    <posX>12</posX>
    <posY>29</posY>
    <title>Senior Developer</title>
  </user>
  <user>
    <id>2022</id>
    <posX>45</posX>
    <posY>87</posY>
    <title>Test22 text</title>
  </user>
</users>

I have a php file with working code to add more users:

$xml = simplexml_load_file("js/data.xml");
    $user = $xml->addChild('user');
    $user->addChild('id',2022);
    $user->addChild('posX',34);
    $user->addChild('posY',67);
    $user->addChild('title','Test33 text');
    // Store new XML code in data.xml
    $xml->asXML("js/data.xml");
    echo $xml->asXML();

This will add a new user into the file. So far so good, no problems here.

If you take a good look at the code, you'll see that this new user I want to add has the same id (2022) as a user in the xml file. This is the same person, so in this case I don't want to add him, but update him. This is where the problems start.

To update him I first need to check if the ID exists. I did some google-ing and searched this site and found a solution given here: php SimpleXML check if a child exists Problem is, I can't get it to work.

This is the modified code of my php file:

$xml = simplexml_load_file("js/data.xml");

//from: https://stackoverflow.com/questions/1560827/php-simplexml-check-if-a-child-exist
if (isset($xml->user->id->2022)) { // c exists
   echo "test";
} else { //else add it
   $user = $xml->addChild('user');
   $user->addChild('id',2022);
   $user->addChild('posX',45);
   $user->addChild('posY',87);
   $user->addChild('title','Test33 text');
}
// Store new XML code in data.xml
$xml->asXML("js/data.xml");
echo $xml->asXML();

So here I try to check if the id exists. If so: echo something, else add the person. Unfortunally, when I run this code I get the following error:

Parse error: syntax error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '{' or '$' 

Anyone has an idea what I do wrong here?

Second problem I have is updating the children (posX, posY and title) if the id exists (ofcourse ONLY the children grouped with this id) . That part of the code needs to be where the test echo is now. I couldn't find a working solution on this site or google using simplexml. Does anyone has an idea how to do this?

Thank you for your time


Solution

  • Rather use xpath() to select a <user>by <id>:

    $xml = simplexml_load_string($x); // assume XML in $x
    
    $id         = "2022";
    list($user) = $xml->xpath("/users/user[id = '$id']") + [NULL];
    

    Now check $user. If your XML has the above ID, $user will contain the SimpleXML element.
    If not, $user will be NULL.

    if (!$user) {
        // create new user
    } else  {
        $user->title = "updated!";
    }
    

    Please note that the [NULL] at the end of line 3 requires PHP >= 5.4, if you don't have it, use:

    list($user) = $xml->xpath("/users/user[id = '$id']") + array(NULL);
    

    see it working: https://eval.in/236618