2017-09-27 53 views
2

Plase,help!
需要刪除第一個元素從DOMNodeList $myDivs,但實際刪除沒有發生 - 元素依然存在。通過​​DOMElement似乎不會從DOMNodeList中刪除

$dom = new DOMDocument(); 
$dom->loadHTML($file); 
$xpath = new DOMXPath($dom); 
$myDivs = $xpath->query('//div[@data-name|data-price]'); 
usleep(1); 
//Must REVERSE iterate DOMNodeList. 
for ($i = $myDivs->length - 1; $i >= 0; $i--) { 
    //Deleting 1st element of (DOMNodeList) $myDivs, containing advertisement product 
    if ($i == 0) { 
    //Removing div element (DOMNode) from DOM? DOMNodeList? Nothing changes 
    $result = $myDivs->item($i)->parentNode->removeChild($myDivs->item($i)); 
    } 
    //Adding formatted string of attributes of valid DOMElements (div) 
    $outputArr[] = printf('%1$s - %2$s, %3$s.<br>', 
         $myDivs->item($i)->getAttribute('data-name'), 
         $myDivs->item($i)->getAttribute('data-price'), 
         $myDivs->item($i)->getAttribute('data-currency')) 
        ?? null; 
} 

for(){}反向迭代,通過XPath和在最後一次迭代中取出($i=0,元素#0)一個DOMElement應當從到處(DOM和的DOMNodeList)吹掃,因爲它從php.net似乎:

Keep in mind that DOMNodelists are "live" - changes to the document or node that the DOMNodelist was derived from will be reflected in the DOMNodelist.

You can modify, and even delete, nodes from a DOMNodeList if you iterate backwards

但它沒有發生!發生

沒有錯誤,$result等於該確切元素#0(意爲removeChild()已完成它的工作正常)

在調試我在行usleep(1);得到$myDivs->length=31,並在線路$outputArr[] =...我仍然有​​相同的長度。
所以,元素#0仍然被附加到$ouputArr,同時不應該...

不能看到我錯過了什麼?

附:當然,這種情況總是可以使用continue跳過迭代,但刪除

+0

我敢打賭,它是在位置1兩次添加項目 –

+0

@PatrickQ,不完全。後來在代碼中,我正在打印'$ outputArr'。所以,我確信元素#0進入'$ outputArr',而souhldn't。它有獨特的內容,所以毫無疑問。 –

回答

2

您未引用官方文檔,而是用戶提供的評論。從XPath查詢返回的DOMNodeLists不是「活的」。 removeChild僅從原始文檔中刪除節點,而不是從DOMNodeList中刪除節點。

+0

嗯,是的。官方文檔沒有提及改變_any_ DOMNodeLists。同樣,關於DOMDocument和DOMXPath的DOMNodeLists之間的差異...... 那麼,沒有辦法編輯XPath查詢導致的DOMNodeLists? –

+0

@ Denis.Z是的,沒有辦法直接修改DOMNodeLists *。如果原始文檔發生更改,某些列表可能會間接更改,但我認爲這僅適用於由'DOMNode :: childNodes'返回的列表。 – nwellnhof

+0

似乎是這樣,謝謝:) –