How to delete / remove nodes in SimpleXML

The other day I was testing and playing with SimpleXML to process some XML documents when I came to a problem – I realized that I needed to delete a node before dumping the XML object to text. However if you are familiar with SimpleXML, it doesn’t come with a down right way to remove nodes like DOMDocument does.

A few searches on Google neither helped – people were just saying how simple SimpleXML was and it simply could not fulfill a task like this.

You know what I did? Yes, just ‘unset‘ the node.

$str = <<<STR
<a>
  <b>
    <c>
    </c>
  </b>
</a>
STR;

$xml = simplexml_load_string($str);
unset($xml –> a –> b –> c); // this would remove node c
echo $xml –> asXML(); // xml document string without node c

There you go!

Related Posts:

Google

8 responses

  1. Niels Kristensen

    Oh so this is how to do it and it seems to be easy  Now I don’t need to bother our IT whenever I want to remove SimpleXML . Thanks for covering this topic dude 

  2. david stokes

    The problem with this approach (and all the approaches I have seen) is that you need to know the the xml tree. What happens if you have multiple nodes of the same type?

    You can use:
    unset($xmlNode->file[$ix]);

    but you still need to know the name of the node you want to delete (above it is “file”).

    Still this approach does allow you to iterate through nodes deleting the ones you want to:

    $ix = count($xmlNode->file);
    for ($ix– ; $ix >= 0 ; $ix–)
    {
    $xmlSubNode = $xmlNode->file[$ix];
    if (doYouWantToDeleteThisNode($xmlSubNode))
    {
    unset($xmlNode->file[$ix]);
    }
    }

    The reason I count backwards is because deleting the nodes causes the later indices to change. You can count up – you just need to make sure that you do not increment your counter variable (ix above) when you delete the node.

  3. CeremCem

    I have faced with the problem that David described, and found a simpler solution at php.net.

    Steps are as follows:
    * Get the node object in any ways (eg. via xpath())
    * import the node as DOM object
    * perform the removal.

    As an example:

    list($theNodeToBeDeleted) = $myXml->xpath($someXPathQuery);
    $oNode = dom_import_simplexml($theNodeToBeDeleted);
    $oNode->parentNode->removeChild($oNode);

    Simple enaugh, huh?

  4. Peter

    I made a class extension based on the code in the last post. In my case I needed to remove nodes by specific attributes and values. So here’s my effort:

    class SimpleXMLExtend extends SimpleXMLElement
    {
    public function addCData($nodename,$cdata_text)
    {
    $node = $this->addChild($nodename); //Added a nodename to create inside the function
    $node = dom_import_simplexml($node);
    $no = $node->ownerDocument;
    $node->appendChild($no->createCDATASection($cdata_text));
    }

    public function removeNodeByAttrib($nodename,$attribute,$value){
    foreach ($this->xpath($nodename) as $key => $node) {
    foreach($node->attributes() as $attrib => $val){
    if ($attrib == $attribute && $val == $value) {
    $oNode = dom_import_simplexml($node);
    }
    }
    }
    $oNode->parentNode->removeChild($oNode);
    }

    }

    Hope this may be helpful for anyone.

    1. geoffrey

      I’m using this class.
      I always receive this error:

      Fatal error: Call to a member function removeChild() on a non-object on line 20.

      And this is line 20 : $oNode->parentNode->removeChild($oNode);

  5. Deleting SimpleXmlElement Child (php) « Youkey

    [...] helper functions is from one of the comments for DOM on php.net and idea about using unset is from kavoir.com. And it works on this [...]

  6. tresloukadu

    @Peter

    thanks it worked very good here!

Leave a reply

Google

Good Boys

Do NOT subscribe, I’m a shameless self-promoter!

Thesis Theme for WordPress:  Options Galore and a Helpful Support Community

We are …

We write with …

Written with Windows Live Writer

We appreciate your …