Проблемы с удалением элементов XML с использованием PHP DOM - PullRequest
2 голосов
/ 12 октября 2008

Вот файл XML, над которым я работаю:

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

index.php, страница, на которой отображается список действий с флажками, кнопка для удаления отмеченных действий и поле для добавления новых действий:

<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>

delete.php, который не работает должным образом:

<?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');
?>

Я протестировал процедуру удаления без цикла, используя жестко запрограммированный произвольный идентификатор, и это сработало. Я также протестировал массив $ atvID, и он правильно напечатал выбранные номера идентификаторов. Когда он находится внутри цикла, выводится ошибка:

Исправляемая фатальная ошибка: Аргумент 1 переданный в DOMNode :: removeChild () должен быть экземпляром DOMNode, с нулевым значением в /directorypath/delete.php по линии 9

Что не так с моим кодом?

Ответы [ 3 ]

2 голосов
/ 12 октября 2008

элементы DOMNodeList индексируются, начиная с 0; Вам нужно переместить $ count ++ в конец цикла while на шаге вывода.

1 голос
/ 15 октября 2008

Хитрость DOMNodeLists состоит в том, что они НЕ являются массивами. Если вы удалите узел, список будет переиндексирован. Это приведет к поломке вашего кода, если пользователь выберет более одного элемента для удаления. Если вы выбрали плавание и бег, плавание и футбол будут удалены.

Возможно, вы захотите начать с предоставления каждому виду деятельности уникального идентификатора, который вы можете искать, скажем, атрибута с именем 'id' (это, вероятно, не будет настоящим идентификатором. GetElementByID () DOM работает только для XML, который имеет DTD, как HTML-страница. Я предполагаю, что вы не хотите туда заходить.)

Вы можете обновить ваш XML, чтобы он выглядел следующим образом.

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

Вы бы использовали эти атрибуты имени вместо $ count в качестве значения внутри ваших флажков.

Затем вы можете использовать xPath для поиска элементов, которые нужно удалить внутри вашего foreach.

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

Надеюсь, это поможет вам начать.

1 голос
/ 14 октября 2008

В дополнение к перемещению $ count ++ в конец цикла while, было бы неплохо иметь проверку delete.php, чтобы убедиться, что $ _POST ['activity'] является числовым и находится в указанном диапазоне, только для убедитесь, что на вашей странице нет сообщений о фатальных ошибках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...