我想用PHP删除一批结点,但是发现删除的时候发现每次只删了一半的结点,有趣但无奈的现象。我的PHP程序:<?php
///*
//读取XML文件,并删除之
$doc = new DOMDocument();
$doc->load( 'gallery.xml' ); $root = $doc->getElementsByTagName("simpleviewergallery");//XML根结点
$root = $root->item(0);
$images = $root->getElementsByTagName('image');//image结点列表 $stepCount = 0;//统计循环次数
$deleteSuccess = false;//用于循环中保存是否删除成功的标志
foreach( $images as $image )
{
$text_caption = $image->getElementsByTagname('caption')->item(0)->nodeValue;//获取结点的内容,以便输出
//$deleteSuccess = $root->removeChild($image);//删除结点

if($deleteSuccess){//删除成功
echo $text_caption . ' has been deleted <hr>';
} else {//删除失败
echo $text_caption . ' delete failed <hr>';
}
//$image->getElementsByTagName( "filename" )->item(0)->nodeValue = 'no caption!!';
$stepCount++;
} $doc->save('out.xml');//输出到out.xml文件

print '循环次数'.$stepCount;
?>XML中共有12个<image> 结点,现在只能遍历6个,就结束程序了把代码中的代码注释掉后(即不删除结点),能够遍历完12个结点。请大家教下我的代码是否有错,我实在找不出来。
XML文件见下面,共12个<image>结点<?xml version="1.0" encoding="UTF-8"?>
<simpleviewergallery>
<image>
<filename>wide.jpg</filename>
<caption>caption 1</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>caption 2</caption>
</image>
<image>
<filename>wide.jpg</filename>
<caption>caption 3</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>caption 4</caption>
</image>
<image>
<filename>wide.jpg</filename>
<caption>Caption 5</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>Caption 6</caption>
</image>
<image>
<filename>wide.jpg</filename>
<caption>Caption 7</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>Caption 8</caption>
</image>
<image>
<filename>wide.jpg</filename>
<caption>Caption 9</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>Caption 10</caption>
</image>
<image>
<filename>wide.jpg</filename>
<caption>Caption 11</caption>
</image>
<image>
<filename>tall.jpg</filename>
<caption>Caption 12</caption>
</image>
</simpleviewergallery>

解决方案 »

  1.   

    removeChild操作会将修改images数组,foreach循环中,第一次循环删除第一个元素,原本第二个元素就变为了第一个,而foreach第二次循环会指向当前的第二个元素,也就是原来的第三个元素,依次类推,实际上最终只能删除6个元素,所以你要删除的话,修改如下:
    for( i = 0; i < count(images); i++){
        ......
        $deleteSuccess = $root->removeChild($image);
        ......
    }
      

  2.   

    啊,写错了,这样还是循环6次,要先取出images的元素个数:
    count_img = count($images);
    for($i=0; $i<count_img; $i++){
        ......
        $deleteSuccess = $root->removeChild($image);
        ......
    }
      

  3.   

    谢谢这位大哥,你说的对我很有启发按照你的意思,作了修改,但还是遇到麻烦,count()函数结果是1而不是期待的12而且用is_array()函数判断后发现$images也不是数组我刚学PHP,对这里的对象与数组不是很清楚如下<?php
            ……

    //判断$images是否数组还是其它东西
    if (is_array($images)) print '$images是数组'; else print '$images不是数组';
            //结果显示不是数组 print '<br />';
    $count_img = count($images);
    print '子元素个数 ' . $count_img . '<br />';

    for ($i=0; $i < $count_img; $i++){
    $image = $images->item(0);
    $deleteSuccess = $root->removeChild($image);
    $stepCount++;
    }
    $doc->save('out.xml');//输出到out.xml文件

    print '循环次数 ' . $stepCount;
    ?>
    结果输出:$images不是数组
    子元素个数 1
    循环次数 1
      

  4.   

    Chrom下没法加载编辑器
    修改后代码
     
    <?php 
            …… //判断$images是否数组还是其它东西 
    if (is_array($images)) print '$images是数组'; else print '$images不是数组'; 
            //结果显示不是数组 print ' <br />'; 
    $count_img = count($images); 
    print '子元素个数 ' . $count_img . ' <br />'; for ($i=0; $i < $count_img; $i++){ 
    $image = $images->item(0); 
    $deleteSuccess = $root->removeChild($image); 
    $stepCount++; 

    $doc->save('out.xml');//输出到out.xml文件 print '循环次数 ' . $stepCount; 
    ?> 
     
      

  5.   

    $root->getElementsByTagName返回的是一个DOMNodeList的对象(具体看PHP的手册),这个对象有一个length属性表示Node的个数,代码可以改为:$count_img = $images->length;
      

  6.   

    谢谢大哥,成功了!
    我对foreach的效率\效果不清楚,
    我会慢慢学好PHP的