tags:

views:

2402

answers:

5

Here's the XML file i'm working on:

<list>
    <activity>swimming</activity>
    <activity>running</activity>
    <activity>soccer</activity>
</list>

The index.php, page that shows the list of activities with checkboxes, a button to delete the checked activities, and a field to add new activities:

<html>
<head></head>
<body>
<?php
    $xmldoc = new DOMDocument();
    $xmldoc->load('sample.xml', LIBXML_NOBLANKS);

    $count = 0;

    $activities = $xmldoc->firstChild->firstChild;
    //prints the list of activities, with checkboxes on the left for each item
    //the $count variable is the id to each entry
    if($activities!=null){
        echo '<form name=\'erase\' action=\'delete.php\' method=\'post\'>' . "\n";
        while($activities!=null){
            $count++;
            echo "    <input type=\"checkbox\" name=\"activity[]\" value=\"$count\"/>";
            echo ' '.$activities->textContent.'<br/>'."\n";
            $activities = $activities->nextSibling;
        }
        echo '    <input type=\'submit\' value=\'erase selected\'>';
        echo '</form>';
    }
?>
//section used for inserting new entries. this feature is working as expected.
<form name='input' action='insert.php' method='post'>
    insert activity:
    <input type='text name='activity'/>
    <input type='submit' value='send'/>
    <br/>
</form>
</body>
</html>

the delete.php, which is not working as expected:

<?php
    $xmldoc = new DOMDocument();
    $xmldoc->load('sample.xml', LIBXML_NOBLANKS);

    $atvID = $_POST['activity'];

    foreach($atvID as $id){
        $delnode = $xmldoc->getElementsByTagName('activity');
        $xmldoc->firstChild->removeChild($delnode->item($id));
    }

    $xmldoc->save('sample.xml');
?>

I've tested the deletion routine without the loop, using an hard-coded arbitrary id, and it worked. I also tested the $atvID array, and it printed the selected id numbers correctly. When it is inside the loop, here's the error it outputs:

Catchable fatal error: Argument 1 passed to DOMNode::removeChild() must be an instance of DOMNode, null given in /directorypath/delete.php on line 9

What is wrong with my code?

+2  A: 

the DOMNodeList items are indexed starting with 0; You need to move the $count++ to the end of the while loop in the output step.

Czimi
that did it... thanks a lot!
David McDavidson
+1  A: 

In addition to moving $count++ to the end of the while loop, it might be a good idea to have delete.php check to make sure the $_POST['activity'] is numeric and within the specified range, just to ensure there are no fatal error messages generated on your page.

ruquay
How should i make the checking?
David McDavidson
+1  A: 

The tricky thing about DOMNodeLists is that they are NOT arrays. If you delete a node, the list will re-index. This will cause your code to break if a user selects more than one item for deletion. If you selected swimming and running, swimming and soccer would be deleted.

You might want to start by giving each activity a unique identifier you can search for, say an attribute called 'id' (this likely wouldn't be a real ID. The DOM's getElementByID() only works for XML that has a DTD, like an HTML page. I'm guessing you don't want to go there.)

You might update you're XML to look like this.

<list>
    <activity name="swimming">swimming</activity>
    <activity name="running">running</activity>
    <activity name="soccer">soccer</activity>
</list>

You'd use these name attributes instead of $count as the value inside your checkboxes.

You can then use xPath to find items to remove inside your foreach.

$xpath = new DOMXPath($xmldoc);
$xmldoc->firstChild->removeChild($xpath->query("/list/activity[@name='$id']")->item(0));

Hope this helps get you started.

John ODonnell
Interesting. As you guessed, i had problems deleting several entries at once precisely because of the re-indexing of the DOM. I resolved that problem in a simpler way, i started the deletion on the largest id. It worked, but your solution got me thinking about xpath, i'll take a look at that.
David McDavidson
A: 

kindly anyone can reupload the code again?

i have checked the above code it fecth the vaules from the xml successfully but when i try to delete it does not delete

if any one can re-upload the working code for delete can be helpful for me.

regards

vicky
I'm sorry, I don't have the code with me anymore
David McDavidson
A: 

Hi all the delete function is working veryy fine. but it has one problem when for example i have the file pic1, pic2, pic 3 but when checkbox at pic 3 and press delete it deltes the pic2, if i delete pic 2 it deletes the pic one.

If i delte the first pic for example pic1 then it gets deleted succesfully

but rest all not working fine kindly check the code now.

load('photos.xml', LIBXML_NOBLANKS);

$count = 0; 

$activities1 = $xmldoc->firstChild->firstChild; 
//prints the list of activities, with checkboxes on the left for each item 
//the $count variable is the id to each entry 
if($activities1!=null){ 
    echo '<form name=\'erase\' action=\'delete.php\' method=\'post\'>' . "\n"; 
    while ($activities1!=null){ 
        echo "    <input type=\"checkbox\" name=\"pic[]\" value=\"$count\"/>"; 
        echo ' '.$activities1->textContent.'<br/>'."\n"; 
        $activities1 = $activities1->nextSibling; 
    } 
    $count++; 
    echo '    <input type=\'submit\' value=\'erase selected\'>'; 
    echo '</form>'; 
} 

?>

delte.php

load('photos.xml', LIBXML_NOBLANKS);

$atvID = $_POST['pic']; 

foreach($atvID as $id){ 
    $delnode = $xmldoc->getElementsByTagName('pic'); 
    $xmldoc->firstChild->removeChild($delnode->item($id)); 
} 

$xmldoc->save('photos.xml'); 

?>

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

ice1.jpg Cheery Pie ala Mode a ice2.jpg Ice Cream Dessert ice3.jpg Ice Cream Tower ice4.jpg Ice Cream and Raspberries ice5.jpg Iced Dessert

vicky
You should ask your own question. Go here and ask again http://stackoverflow.com/questions/ask
David McDavidson