dnelson
dnelson

Reputation: 467

How to remove XML elements and all children?

I need to read an XML file and delete all the elements named <images> and all the children associated. I have found similar old questions that did not work. What am I doing wrong? Is there a better method?

XML:

<?xml version='1.0' encoding='UTF-8'?>
<settings>
  <background_color>#000000</background_color>
  <show_context_menu>yes</show_context_menu>
  <image>
    <thumb_path>210x245.png</thumb_path>
    <big_image_path>620x930.png</big_image_path>
  </image>
  <image>
    <thumb_path>200x295.png</thumb_path>
    <big_image_path>643x950.png</big_image_path>
  </image>
</settings>

PHP:

$dom = new DOMDocument();
$dom->load('test.xml');
$thedocument = $dom->documentElement;
$elements = $thedocument->getElementsByTagName('image');

foreach ($elements as $node) {
  $node->parentNode->removeChild($node);
}

$save = $dom->saveXML();
file_put_contents('test.xml', $save)

Upvotes: 1

Views: 750

Answers (3)

dnelson
dnelson

Reputation: 467

I figured it out after a good night of sleep. It was quite simple actually.

$xml = simplexml_load_file('test.xml');
unset($xml->image);
$xml_file = $xml->asXML();
$xmlFile = 'test.xml';
$xmlHandle = fopen($xmlFile, 'w');
fwrite($xmlHandle, $xml_file);
fclose($xmlHandle);

Edit: You probably want to make it save directly:

$file = 'test.xml';

$xml = simplexml_load_file($file);
unset($xml->image);
$success = $xml->asXML($file);

See SimpleXMLElement::asXML()Docs.

Upvotes: 2

michi
michi

Reputation: 6625

First of all, your XML is broken, see <thumb>...</thumb_path>and next line as well -> fix it!

Then, real simple in 3 lines of code:

$xml = simplexml_load_string($x); // $x holds your xml
$count = $xml->image->count()-1;
for ($i = $count;$i >= 0;$i--) unset($xml->image[$i]);

See live demo @ http://codepad.viper-7.com/HkGy5o

Upvotes: 1

Berti
Berti

Reputation: 76

In the PHP Manual page (where you should always go 1st :-) one awesome contributor points out that:

You can't remove DOMNodes from a DOMNodeList as you're iterating over them in a foreach loop.

Then goes on to offer a potential solution. Try something like this instead:

  <?php
    $domNodeList = $domDocument->getElementsByTagname('p');
    $domElemsToRemove = array();
    foreach ( $domNodeList as $domElement ) {
      // ...do stuff with $domElement...
      $domElemsToRemove[] = $domElement;
    }
    foreach( $domElemsToRemove as $domElement ){
      $domElement->parentNode->removeChild($domElement);
    }
    ?>

Upvotes: 1

Related Questions