DomDocument removeChild in foreach 重新索引 dom

roh*_*ora 7 html javascript php dom domdocument

我正在尝试删除p带有data-spotid属性的标签

        $dom = new DOMDocument();
        @$dom->loadHTML($description);
        $pTag = $dom->getElementsByTagName('p');

        foreach ($pTag as $value) {
            /** @var DOMElement $value */
            $id = $value->getAttribute('data-spotid');
            if ($id) {
                $value->parentNode->removeChild($value);
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是当我删除孩子时,它正在重新索引 dom。假设我有 8 个项目,我第一次删除它会重新索引它,第二个元素将成为第一个,它不会删除它将转到第二个,现在是第三个元素。

Ant*_*ony 5

在文档的几条评论中提到了这一点DomNode::removeChild,问题显然是 foreach 上的迭代器指针如何无法处理这样的事实:您在循环子级列表时从父级数组中删除项目(或某物)。

建议的修复方法是首先循环主节点并将要删除的子节点推送到其自己的数组中,然后循环该“待删除”数组并从其父节点中删除这些子节点。例子:

$dom = new DOMDocument();
@$dom->loadHTML($description);
$pTag = $dom->getElementsByTagName('p');

$spotid_children = array();

foreach ($pTag as $value) {
    /** @var DOMElement $value */
    $id = $value->getAttribute('data-spotid');
    if ($id) {
        $spotid_children[] = $value; 
    }
}

foreach ($spotid_children as $spotid_child) {
    $spotid_child->parentNode->removeChild($spotid_child); 
}
Run Code Online (Sandbox Code Playgroud)