这是我正在处理的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');
?>
我已经使用硬编码的任意id测试了没有循环的删除例程,并且它有效。我还测试了$ atvID数组,它正确打印了所选的id号。当它在循环内部时,这是它输出的错误:
可捕获的致命错误:参数1 传递给DOMNode :: removeChild()必须 是DOMNode的一个实例,null给定 在 /directorypath/delete.php 第9行
我的代码出了什么问题?
答案 0 :(得分:2)
DOMNodeList项的索引从0开始; 您需要在输出步骤中将$ count ++移动到while循环的末尾。
答案 1 :(得分:1)
除了将$ count ++移动到while循环结束之外,最好让delete.php检查以确保$ _POST ['activity']是数字且在指定范围内,只是为了确保页面上没有生成致命错误消息。
答案 2 :(得分:1)
关于DOMNodeLists的棘手问题是它们不是数组。如果删除节点,列表将重新编制索引。如果用户选择多个项目进行删除,这将导致代码中断。如果您选择游泳和跑步,游泳和足球将被删除。
您可能希望首先为每个活动提供一个可以搜索的唯一标识符,例如一个名为“id”的属性(这可能不是真正的ID .DOM的getElementByID()仅适用于具有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));
希望这有助于您入门。