我遇到了 DOM 方法的一個令人費解的行為removeChild。當回圈遍歷 DOMElement 的子節點時,沿途移除這些節點之一會中斷回圈,即回圈不會遍歷剩余的子節點。
這是一個最小的例子:
$test_string = <<<XML
<test>
<text>A sample text with <i>mixed content</i> of <b>various sorts</b></text>
</test>
XML;
$test_DOMDocument = new DOMDocument();
$test_DOMDocument->loadXML($test_string);
$test_DOMNode = $test_DOMDocument->getElementsByTagName("text");
foreach ($test_DOMNode as $text) {
foreach ($text->childNodes as $node) {
if (preg_match("/text/", $node->nodeValue)) {
echo $node->nodeValue;
$node->parentNode->removeChild($node);
} else {
echo $node->nodeValue;
}
}
}
如果我注釋掉該行$node->parentNode->removeChild($node);,那么輸出是整個測驗字串,即A sample text with mixed content of various sorts,正如預期的那樣。但是,使用該行,僅輸出第一個子節點,即A sample text with. 也就是說,在回圈經過時洗掉第一個子節點顯然會中斷回圈;剩余的子節點不被處理。這是為什么?
在此先感謝您的幫助!
uj5u.com熱心網友回復:
實施對我的問題的評論建議,我想出了以下解決方案:
$test_string = <<<XML
<test>
<text>A sample text with <i>mixed content</i> of <b>various sorts</b></text>
</test>
XML;
$test_DOMDocument = new DOMDocument();
$test_DOMDocument->loadXML($test_string);
$test_DOMNode = $test_DOMDocument->getElementsByTagName("text");
foreach ($test_DOMNode as $text) {
$child_nodes = $text->childNodes;
for($n = $child_nodes->length-1; $n >= 0; --$n) {
$node = $child_nodes->item($n);
if (preg_match("/text/", $node->nodeValue)) {
echo $node->nodeValue;
$node->parentNode->removeChild($node);
} else {
echo $node->nodeValue;
}
}
}
也就是說,我使用另一個帖子中建議的方法以相反的順序遍歷子節點。這樣,所有節點都被處理:輸出為various sorts of mixed contentA sample text with. 注意文本片段的相反順序。在我的特定用例中,這種反轉并不重要,因為我實際上并沒有回顯文本節點,而是對它們執行另一種操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/444165.html
上一篇:通過在PowerShell中不輸入任何內容按Enter來執行命令
下一篇:Svelte:為什么DOM元素屬性(offsetHeight、scrollHeight等)在beforeUpdate中有效?
