2

これが私が取り組んでいる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番号が正しく出力されました。ループ内にある場合、出力されるエラーは次のとおりです。

キャッチ可能な致命的なエラー:DOMNode :: removeChild()に渡される引数1は、DOMNodeのインスタンスである必要があり、9行目の/directorypath/delete.phpでnullが指定されています。

私のコードの何が問題になっていますか?

4

3 に答える 3

2

DOMNodeList 項目のインデックスは 0 から始まります。出力ステップの while ループの最後に $count++ を移動する必要があります。

于 2008-10-12T17:52:54.527 に答える
1

$count++ を while ループの最後に移動することに加えて、delete.php で $_POST['activity'] が数値であり、指定された範囲内にあることを確認することをお勧めします。ページで致命的なエラー メッセージが生成されていません。

于 2008-10-13T20:39:52.300 に答える
1

DOMNodeLists のトリッキーな点は、それらが配列ではないということです。ノードを削除すると、リストのインデックスが再作成されます。これにより、ユーザーが削除するアイテムを複数選択すると、コードが壊れます。水泳とランニングを選択すると、水泳とサッカーが削除されます。

各アクティビティに検索可能な一意の識別子、たとえば「id」という属性を与えることから始めたいと思うかもしれません (これは実際の ID ではない可能性があります。DOM の getElementByID() は、次のような DTD を持つ XML に対してのみ機能します)。 HTML ページです。おそらく、そこに行きたくないでしょう。)

XML を次のように更新することができます。

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

チェックボックス内の値として $count の代わりにこれらの name 属性を使用します。

その後、xPath を使用して、foreach 内で削除する項目を見つけることができます。

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

これが開始に役立つことを願っています。

于 2008-10-15T01:23:14.537 に答える