DomDocument removeChild在重新绑定dom的foreach中 [英] DomDocument removeChild in foreach reindexing the dom

查看:108
本文介绍了DomDocument removeChild在重新绑定dom的foreach中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用 data-spotid 属性来删除 p 标签

  $ dom = new DOMDocument(); 
@ $ dom-> loadHTML($ description);
$ pTag = $ dom-> getElementsByTagName('p');
$ b foreach($ pTag as $ value){
/ ** @var DOMElement $ value * /
$ id = $ value-> getAttribute('data-spotid' );
if($ id){
$ value-> parentNode-> removeChild($ value);


$ / code>

但是当我删除孩子时,它重新绑定了dom 。让我们假设我有8个项目,我删除第1次它将重新编译它,第2个元素将成为第1,它不会删除它会去第2个现在是第3个元素。

解决方案

DomNode :: removeChild 文档,问题显然是foreach上的迭代器指针不能处理从父项中移除项目的事实数组,同时循环遍历儿童列表(或其他)。

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

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

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


$ b foreach($ spotid_children as $ spotid_child){
$ spotid_child-> parentNode-> removeChild($ spotid_child);
}


I am trying to delete p tags with data-spotid attribute

        $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);
            }
        }

but when i am removing child it is reindexing the dom. let suppose i have 8 items i deleted 1st it will reindex it and 2nd element will become 1st and it will not delete it will go to 2nd which is now 3rd element.

解决方案

This is mentioned in a couple of comments on the DomNode::removeChild documentation, with the issue apparently being how the iterator pointer on the foreach not being able to deal with the fact that you are removing items from a parent array while looping through the list of children (or something).

The recommended fix is to loop through the main node first and push the child nodes you want to delete to its own array, then loop through that "to-be-deleted" array and deleting those children from their parent. Example:

$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); 
}

这篇关于DomDocument removeChild在重新绑定dom的foreach中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆