Hi there,

I am trying to delete XML nodes using PHP. Here is a sample of my xml file.

<users>
     <user>
     <fullname>PC1</fullname>
     <floor>4</floor>
     </user>
     <user>
     <fullname>PC2</fullname>
     <floor>3</floor>
     </user>
</users>

Here is my code so far:

<?php

$users = new DOMDocument();
$users->load("officedata.xml");
$suser = simplexml_load_file("officedata.xml");
$count = 0;

foreach($suser->user as $user) {

     if ($user['fullname'] == "PC1") {
    $users->documentElement->removeChild($users-       documentElement->childNodes->item($count));
    $count--;
    }
    $count++
}
$users->save("officedata.xml");

?>

Any idea why this won't work? If I remove the IF statement, all of the XML data gets removed. I am just trying to remove "PC1"

Thanks in advance,

Mapper

For those of you could not figure this one out, after a few tries I got it:

$users = new DOMDocument();
$users->load("officedata.xml");

$suser = simplexml_load_file("officedata.xml");
$count = 0;

$user = $users->getElementsByTagName("user");

foreach($user as $value)
{
   $count++;
   $tasks = $value->getElementsByTagName("fullname");
   $task  = $tasks->item(0)->nodeValue;

   if ($task == "PCID4") {
    $users->documentElement->removeChild($users->documentElement->childNodes->item($count));
   }
}

$users->save("officedata.xml");
?>

Works like a charm and is a very useful code snippet for deleting XML records using PHP!

Mapper
http://www.freegooglewaveinvites.com

This is an absolutely perfect solution! Thanks Mapper!!

I have found that this code is unreliable. Try this and see. Here is the XML:

<users>
     <user>
     <fullname>1</fullname>
     <floor>4</floor>
     </user>
     <user>
     <fullname>2</fullname>
     <floor>3</floor>
     </user>
     <user>
     <fullname>3</fullname>
     <floor>3</floor>
     </user>

</users>

Run the code with this If statement:

if ($task == "3") {

XML record #2 gets deleted instead of #3!!!

Resulting XML:

<users>
     <user>
     <fullname>1</fullname>
     <floor>4</floor>
     </user>
     
     <user>
     <fullname>3</fullname>
     <floor>3</floor>
     </user>

</users>

Also, if any of the tags had no data, they get converted to short notation:
<floor></floor> gets changed to <floor/>

This is the strangest thing! Any idea why this is happening?

Thanks!

Mapper

I have found that this code is unreliable.

Also, if any of the tags had no data, they get converted to short notation:
<floor></floor> gets changed to <floor/>

This is the strangest thing! Any idea why this is happening?

Thanks!

Mapper

After I posted the "works" post, it found it does exactly what you are saying. I couldn't figure out why it's doing what it's doing. I thought maybe it was a white-space issue. The reason the if ($task == "3") deletes record 2 is that the count starts at 0 and not 1, so that makes sense.

I did find another solution that deletes the correct entry. I can't remember where I found it, but I did not write it. So here it goes and it may be a little long, but I'll explain what each section is doing:

<form enctype="multipart/form-data" action="action.php" method="POST">
    <select name="caption">
    
    <?php 
  $imagess = simplexml_load_file('xml/file.xml');
  foreach ($imagess->pic as $pic) {
      foreach ($pic->caption as $caption) { 
          echo "<option value='" . $caption . "'>" . $caption . "</option>"; 
      } 
  } 
  ?> 
  	</select>
    <input type="hidden" name="category" value="furniture" />
    <p><input type="submit" value="Delete Entry" /></p>
    </form>

The code above is my form that pulls the information I want from the XML (the <caption> node) and echoes it into a drop down select list. This form then submits to the furnituredelete.php which contains the XML removal code.

action.php:

$desc = $_POST["caption"]; // gets the caption data from the form
$category = $_POST["category"]; // gets the category data from the from. There are a couple if/else if statements. 

if ($category == "furniture") { // if statement, pretty self-explanatory

$xmlfile = "xml/file.xml"; 
$xmlstr = file_get_contents("$xmlfile"); 
$xml = new simplexmlElement($xmlstr);

$count = 0; //this is important. it sets the count at 0 so it targets the correct node.
foreach ($xml as $pic){ 
if ($pic->caption == $desc){ 
unset($xml->pic[$count]); break; 
} 
$count++; // This is the important line as it updates the node count.
} 

echo "<div style='padding:50px;'><p style='font-family:Arial, Helvetica, san-serif; color:#666; font-size:1em;'>" . $desc . " has been deleted.<br /><a href='home.php'>Back to home page</a></p><p><a href='furn.php'>Back to Furniture delete page</a></p>";


$handle = fopen("$xmlfile", "w"); //opens the xml and sets it for writing
fwrite($handle, $xml->asXML()); //overwrites file and saves
fclose($handle); // closes xml file

exit; 
} else {} 
//code actually has 2 more if statements, but it's not necessary for this example.

Here's the XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<imagess>
    
    <pic>
        <images>images/furniture/2.gif</images>
        <tag>images/sold.png</tag>
		<caption>1950's vintage chair</caption>
    </pic>
    <pic>
        <images>images/furniture/3.gif</images>
        <tag>images/forsale.png</tag>
		<caption>celadon vintage velvet swivel chair</caption>
    </pic>
    <pic>
        <images>images/furniture/4.gif</images>
        <tag>images/forsale.png</tag>
		<caption>bamboo barrel chair </caption>
    </pic>
    <pic>
        <images>images/furniture/5.gif</images>
        <tag>images/sold.png</tag>
		<caption>ivory damasked armoire in aged french blue</caption>
    </pic>

</imagess>

Hopefully that helps you out. I'm pretty new at PHP and what not, but was able to adjust the code to get it to work for my needs.

Edited 6 Years Ago by disinfor: update

This article has been dead for over six months. Start a new discussion instead.