Search code examples
phpxmlxpathsimplexml

Updating XML node value with SimpleXML API


I have an XML structure:

<root>
   <!-- ... -->
   <B ID="444">
        <C></C>  
        <D>Anything</D>
        <E>
            <child1 /*expected outcome came in here*/> /*sometimes here*/ </child1>
            <child2>data2 <!-- instead of here --></child2>
            <child3>data3</child3>
            <child4>data4 /* and also here instead*/ </child4>
        </E>
    </B>
   <!-- ... -->
</root>

I made an XPath query to fetch //*B, where child2==data2 and child4==data4, like this:

$query = "//*[@ID=444]//*['data2' and 'data4']";
$result = $xml->xpath($query);

it worked fine. But now, I want to update data1 and data3, after finding a match, using only the simplexml API. Here's what i did, but it's not working correctly:

if(!empty($result)){
    $result[0]['data2'] = "Blabla";
    $result[0]['data4'] = "Blaaaaaaaa";
    return $xml->saveXML($File;
}

What am I doing wrong? Or how is it better done with simplexml? Any idea will be appreciated.


Solution

  • I made an XPath query to fetch //*B, where child2==data2 and child4==data4, like this:

    $query = "//*[@ID=444]//*['data2' and 'data4']";
    

    That's wrong already. Where do you think does your attempt compare child2 with 'data2' or child4 with 'data4'?

    Better:

    $query = "//B[@ID = 444 and .//child2 = 'data2' and .//child4 = 'data4']";
    $result = $xml->xpath($query);
    
    foreach ($result as $b) {
        // find first <child2> and <child4> descendants
        $child2 = $b->xpath(".//child2")[0];
        $child4 = $b->xpath(".//child4")[0];
    
        // set their text values
        $child2[0] = "Blabla";
        $child4[0] = "Blaaaaaaaa";
    }
    
    return $xml->saveXML($File);
    

    See http://ideone.com/lXtvbP