Please Help! Deleting XML node(s)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
oldnoisy
Forum Newbie
Posts: 12
Joined: Sat Sep 12, 2009 7:49 pm

Please Help! Deleting XML node(s)

Post by oldnoisy »

Hi all, I'm brand new to this forum and hope to contribute as well as learn as time goes on. I'm in the process of teaching myself PHP, so I may be missing something rather obvious to experienced coders (so please be lenient!)

As for this problem, I've done extensive research on the matter but cannot come up with a solution. I'm writing a image gallery manager editable easily by my clients. The admin uploads an image via PHP form, a script resizes it and adds an entry into an XML file. A flash gallery then reads the XML file and displays images for users. That part is all set up. The problem is when admin tries to delete image, everything works except deleting the XML reference to said image.

I suspect the problem lies in that each XML entry's tag is the same as the others. It's not <image1>, <image2>, etc as you can see. So I have to search by node value then delete said node and parent (I think?).

I receive no PHP errors from server when running this.

Below is 'gallery.xml'

Code: Select all

 
<image>
<filename>1252534809.jpg</filename>
<caption>Fun time coding PHP!!</caption>
</image>
 
checked[] refers to the array of images selected on previous page for deletion.

Code: Select all

 
 
 
if (isset($_POST['submit'])) {
    $checked = $_POST["checked"];
    $how_many = count($checked);
    echo $how_many.' file(s) successfully deleted.';
    
    if ($how_many>0) {
        
    }
    for ($i=0; $i<$how_many; $i++) {
        if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i])){
        unlink('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i]);
        }
        if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i])){
        unlink('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i]);
        }
    }
 
//Remove XML reference to deleted image
    $xmlfile = "gallery.xml"; 
    $xmlstr = file_get_contents("$xmlfile"); 
    $xml = new SimpleXMLElement($xmlstr);
 
    $count = 0; 
    foreach ($xml as $image){ 
        
        for ($i=0; $i<$how_many; $i++) {
            if ($image->filename == $checked[i]){ 
            unset($xml->image[$count]); break; 
        }
    
    } 
    $count++; 
    } 
    
    $handle = fopen("$xmlfile", "w"); 
    fwrite($handle, $xml->asXML()); 
    fclose($handle); 
    
    echo $xml->asXML();
    echo $xml->saveXML();
}
 
 

Thanks so much for any help,


oldnoisy
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Please Help! Deleting XML node(s)

Post by John Cartwright »

It is always good practice to develop with atleast

Code: Select all

error_reporting(E_ALL);
set to detect any warnings. In doing so, you would realize that on this line

Code: Select all

if ($image->filename == $checked[i]){
you are missing a $ for the "i" variable, i.e.

Code: Select all

$checked[i]
should be

Code: Select all

$checked[$i]
Everything else looks ok at first glance.
oldnoisy
Forum Newbie
Posts: 12
Joined: Sat Sep 12, 2009 7:49 pm

Re: Please Help! Deleting XML node(s)

Post by oldnoisy »

Thanks a lot John.. I guess staring at code long enough can make one miss simple mistakes. I'll try the error reporting next time.

Unfortunately, it doesn't delete more than one image from the XML now, I get

Warning: main() [function.main]: Node no longer exists in /home/content/m/u/c/muchomungo/html/phpmanager/deleted.php on line 39


line 39 is the foreach ($xml as $image) bit.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Please Help! Deleting XML node(s)

Post by John Cartwright »

What is the inner for() loop supposed to be doing? From what I understand, you can omit it, and do something like

Code: Select all

 
$count = 0;
foreach ($xml as $image){
   if (in_array($image->filename, $checked)) {
      unset($xml->image[$count]);
   }
   $count++;
}
Note, this will loop your entire xml file, so it would be recommended to check how many images have been deleted against how many were requested, and when satisfied break out of the loop.
oldnoisy
Forum Newbie
Posts: 12
Joined: Sat Sep 12, 2009 7:49 pm

Re: Please Help! Deleting XML node(s)

Post by oldnoisy »

Okay I've decided to redo the angle I'm coming from, now it's:

Unfortunately it still adds the XML referencing the deleted files back in :banghead:

Code: Select all

 
<?PHP
 
error_reporting(E_ALL);
 
 
if(!empty($_POST['submit'])) { 
    $checked = $_POST['checked']; 
    $how_many = count($checked); 
     
    if ($how_many > 0) { 
        //Delete image files 
        for ($i = 0; $i < $how_many; $i++) { 
            if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i])){ 
                @unlink('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i]); 
            } 
            if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/thumbs/'.$checked[$i])){ 
                @unlink('/home/content/m/u/c/muchomungo/html/phpmanager/thumbs/'.$checked[$i]); 
            } 
        } 
        
    //Remove references from XML File 
        $xml_file = 'gallery.xml'; 
        $xml = simplexml_load_file($xml_file); 
 
        //Re-make XML --- MAKES A BETTER XML OUTPUT 
        $xml_out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
        $xml_out .= "<simpleviewergallery maxImageWidth=\"480\" maxImageHeight=\"480\" textColor=\"0xFFFFFF\" frameColor=\"0xFFFFFF\" frameWidth=\"20\" stagePadding=\"40\" navPadding=\"40\" thumbnailColumns=\"3\" thumbnailRows=\"3\" navPosition=\"left\" vAlign=\"center\" hAlign=\"center\" title=\"Maxs Tattoos\" enableRightClickOpen=\"true\" backgroundImagePath=\"\" imagePath=\"\" thumbPath=\"\">\n"; 
        foreach($xml as $image) { 
            //Check every image on the XML file 
            for ($i = 0; $i < $how_many; $i++) { 
                //Check every image checked 
                if ($image->filename != $checked[$i]){  
                    //Add image into the output if is not checked 
                    $xml_out .= "    <image>\n"; 
                    $xml_out .= "        <filename>". $image->filename ."</filename>\n"; 
                    $xml_out .= "        <caption>". $image->caption ."</caption>\n"; 
                    $xml_out .= "    </image>\n"; 
                } 
            } 
        } 
                     
        $xml_out .= "</simpleviewergallery>"."\n"; 
                         
        //Write XML 
        $handle = fopen($xml_file, 'w'); 
        fwrite($handle, $xml_out); 
        fclose($handle); 
         
        //Results 
        echo $how_many.' file(s) successfully deleted.'; 
    } else { 
        //No files selected 
        echo 'No files selected.'; 
    } 
}
 
?>
 
 
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Please Help! Deleting XML node(s)

Post by John Cartwright »

Again, why the inner for() loop?

And what happens when you try the code I posted earlier?

For whatever reason you decide to remake the entire xml file, the same concept applies.

Code: Select all

       foreach($xml as $image) {
                if (!in_array($image->filename, $checked)) {
                    //Add image into the output if is not checked
                    $xml_out .= "    <image>\n";
                    $xml_out .= "        <filename>". $image->filename ."</filename>\n";
                    $xml_out .= "        <caption>". $image->caption ."</caption>\n";
                    $xml_out .= "    </image>\n";
                }
        }
oldnoisy
Forum Newbie
Posts: 12
Joined: Sat Sep 12, 2009 7:49 pm

Re: Please Help! Deleting XML node(s)

Post by oldnoisy »

John Cartwright wrote:Again, why the inner for() loop?

And what happens when you try the code I posted earlier?
I don't think it will work because the for loop is for cycling through the $checked array in case the user has selected multiple files to delete.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Please Help! Deleting XML node(s)

Post by John Cartwright »

I amended my last post, take a look.

Basically, you wouldn't need to for() loop because you are already looping each individual image element in xml, and thus only need to validate if that value exists in the checkbox array.
oldnoisy
Forum Newbie
Posts: 12
Joined: Sat Sep 12, 2009 7:49 pm

Re: Please Help! Deleting XML node(s)

Post by oldnoisy »

I don't really understand what happened when I took out the for() loop but... you're right it works! Multiple images, single one, everything. Thanks a ton John! Here is the final

Code: Select all

 
if(!empty($_POST['submit'])) { 
    $checked = $_POST['checked']; 
    $how_many = count($checked); 
    print_r($checked);
    if ($how_many > 0) { 
        //Delete image files 
        for ($i = 0; $i < $how_many; $i++) { 
            if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i])){ 
                @unlink('/home/content/m/u/c/muchomungo/html/phpmanager/images/'.$checked[$i]); 
            } 
            if(file_exists('/home/content/m/u/c/muchomungo/html/phpmanager/thumbs/'.$checked[$i])){ 
                @unlink('/home/content/m/u/c/muchomungo/html/phpmanager/thumbs/'.$checked[$i]); 
            } 
        } 
        
    //Remove references from XML File 
        $xml_file = 'gallery.xml'; 
        $xml = simplexml_load_file($xml_file); 
 
        //Re-make XML --- MAKES A BETTER XML OUTPUT 
        $xml_out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
        $xml_out .= "<simpleviewergallery maxImageWidth=\"480\" maxImageHeight=\"480\" textColor=\"0xFFFFFF\" frameColor=\"0xFFFFFF\" frameWidth=\"20\" stagePadding=\"40\" navPadding=\"40\" thumbnailColumns=\"3\" thumbnailRows=\"3\" navPosition=\"left\" vAlign=\"center\" hAlign=\"center\" title=\"Maxs Tattoos\" enableRightClickOpen=\"true\" backgroundImagePath=\"\" imagePath=\"\" thumbPath=\"\">\n"; 
        foreach($xml as $image) {
                if (!in_array($image->filename, $checked)) {
                    //Add image into the output if is not checked
                    $xml_out .= "    <image>\n";
                    $xml_out .= "        <filename>". $image->filename ."</filename>\n";
                    $xml_out .= "        <caption>". $image->caption ."</caption>\n";
                    $xml_out .= "    </image>\n";
                }
        }
                     
        $xml_out .= "</simpleviewergallery>"."\n"; 
                         
        //Write XML 
        $handle = fopen($xml_file, 'w'); 
        fwrite($handle, $xml_out); 
        fclose($handle); 
         
        //Results 
        echo $how_many.' file(s) successfully deleted.'; 
    } else { 
        //No files selected 
        echo 'No files selected.'; 
    } 
}
 
 
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Please Help! Deleting XML node(s)

Post by John Cartwright »

Great! I edited my last post again I'm not sure if you caught the quasi-explanation or not.

Regardless, glad you got it working :)
Post Reply