我正在学习使用PHP中提供的DOM *类,并且已经注意到(我认为是)测试中的异常。
给定此文档,ZuqML_test_100.html
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:zuq="http://localhost/~/zuqml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<h1>
<zuq:data name="siteHeader" />
</h1>
<h2>
<zuq:data name="pageHeaderName" />
<span> | </span>
<zuq:data name="pageHeaderTitle" />
</h2>
<zuq:region name="post">
<zuq:param name="onEmpty">
<div class="post noposts">
<p>There are no posts to show at this time.</p>
</div>
</zuq:param>
<div class="post">
<h3><zuq:data name="postHeader" /></h3>
<p>
<zuq:data name="postText">
<zuq:format type="trim">
<zuq:param name="length">300</zuq:param>
<zuq:param name="append">
<a>
<zuq:attr name="href">
./?action=viewpost&id=<zuq:data name="postId" />
</zuq:attr>
<zuq:data name="postAuthor" />
</a>
</zuq:param>
</zuq:format>
</zuq:data>
</p>
</div>
</zuq:region>
</body>
</html>
我试图将所有
<zuq:data />
节点替换为值为foo
的简单文本节点。我正在使用以下代码段进行此操作:$root = new DOMDocument();
@$root->load('ZuqML_test_100.html');
foreach($root->getElementsByTagNameNS($root->lookupNamespaceURI('zuq'), 'data') as $node){
$node->parentNode->replaceChild($node->ownerDocument->createTextNode('foo'), $node);
}
echo $root->saveXML();
它可以正常工作,但是我的输出似乎仍然包含
<zuq:data />
节点,如下所示:<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:zuq="http://ichorworkstudios.no-ip.org/~/zuqml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<h1>
foo
</h1>
<h2>
<zuq:data name="pageHeaderName"></zuq:data>
<span>—</span>
foo
</h2>
<zuq:region name="post">
<zuq:param name="onEmpty">
<div class="post noposts">
<p>There are no posts to show at this time.</p>
</div>
</zuq:param>
<div class="post">
<h3><zuq:data name="postHeader"></zuq:data></h3>
<p>
foo
</p>
</div>
</zuq:region>
</body>
</html>
为什么有些
<zuq:data />
节点被遗忘了? 最佳答案
我认为这与您的迭代方式有关。您要在迭代结果列表时对其进行更改,因此最终会破坏效果(副作用)。尝试将循环更改为此:
$nodes = $root->getElementsByTagNameNS($root->lookupNamespaceURI('zuq'), 'data');
$i = $nodes->length - 1;
while ($i >= 0) {
$node = $nodes->item($i);
$node->parentNode->replaceChild(
$node->ownerDocument->createTextNode('foo'),
$node
);
$i--;
}
基本上,它只是向后遍历节点列表,所以当删除节点时,它们是从末尾而不是从开头删除的。