Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Delete XML Element

Tags:

php

xml

I need to delete elements of an XML file using PHP. It will be done via ajax and I need to find the XML element via an attribute.

This is my XML file

<?xml version="1.0" encoding="utf-8"?>
<messages>
    <message time="1248083538">
        <name>Ben</name>
        <email>Ben's Email</email>
        <msg>Bens message</msg>
    </message>
    <message time="1248083838">
        <name>John Smith</name>
        <email>[email protected]</email>
        <msg>Can you do this for me?</msg>
    </message>
</messages>

So what I would say is something like delete the element where the time equals 1248083838.

Ive been using Simple XML up until now and I've just realised it can do everything except delete elements.

So how would I do this?

like image 440
Ben Shelock Avatar asked Jul 20 '09 13:07

Ben Shelock


3 Answers

Dave Morgan is correct in that DOM classes are more powerful, but in case you want to stick with SimpleXML, try using the unset() function on any node, and that node will be removed from the XML.

unset($simpleXMLDoc->node1->child1)
like image 74
Salty Avatar answered Oct 15 '22 15:10

Salty


You can use the DOM classes in PHP. ( http://us3.php.net/manual/en/intro.dom.php ).

You will need to read the XML document into memory, use the DOM classes to do manipulation, and then you can save out the XML as needed (to http or to file).

DOMNode is an object in there that has remove features (to address your question).

It's a little more complicated than SimpleXML but once you get used to it, it's much more powerful

(semi-taken from a code example at php.net)

<?php

$doc = new DOMDocument; 
$doc->load('theFile.xml');

$thedocument = $doc->documentElement;

//this gives you a list of the messages
$list = $thedocument->getElementsByTagName('message');

//figure out which ones you want -- assign it to a variable (ie: $nodeToRemove )
$nodeToRemove = null;
foreach ($list as $domElement){
  $attrValue = $domElement->getAttribute('time');
  if ($attrValue == 'VALUEYOUCAREABOUT') {
    $nodeToRemove = $domElement; //will only remember last one- but this is just an example :)
  }
}

//Now remove it.
if ($nodeToRemove != null)
$thedocument->removeChild($nodeToRemove);

echo $doc->saveXML(); 
?>

This should give you a little bit of an idea on how to remove the element. It will print out the XML without that node. If you wanted to send it to file, just write the string to file.

like image 23
Dave Morgan Avatar answered Oct 15 '22 14:10

Dave Morgan


Even though SimpleXML doesn't have a detailed way to remove elements, you can remove elements from SimpleXML by using PHP's unset(). The key to doing this is managing to target the desired element. At least one way to do the targeting is using the order of the elements. First find out the order number of the element you want to remove (for example with a loop), then remove the element:

$target = false;
$i = 0;
foreach ($xml->message as $m) {
  if ($m['time']=='1248083838') { $target = $i; break; }
  $i++;
}
if ($target !== false) {
  unset($xml->message[$target]);
}

You can even remove multiple elements with this, by storing the order number of target items in an array. Just remember to do the removal in a reverse order (array_reverse($targets)), because removing an item naturally reduces the order number of the items that come after it.

Admittedly, it's a bit of a hackaround, but it seems to work fine.

like image 3
Ilari Kajaste Avatar answered Oct 15 '22 14:10

Ilari Kajaste