DOMDocument::getElementsByTagName方法实际上会返回所有标记,如果第一个参数是'*'。但是你的代码在第一次迭代时用一个文本节点代替
标签(包括所有子节点)。迭代的节点,并修改只有nodeType属性等于XML_TEXT_NODE节点:
$nodes = $dom->getElementsByTagName('*');
foreach ($nodes as $node) {
for ($child = $node->firstChild; $child; $child = $child->nextSibling) {
if (! ($child->nodeType === XML_TEXT_NODE && trim($child->textContent))) {
continue;
}
// The textContent is writable since PHP 5.6.1
if (PHP_VERSION_ID >= 50601) {
$child->textContent .= 'MODIFIED';
continue;
}
// For older versions, create DOMText explicitly
$text = new DOMText($child->textContent . 'MODIFIED');
try {
if ($child->parentNode->replaceChild($text, $child))
$child = $text;
} catch (Exception $e) {
trigger_error("Failed to modify text '$child->textContent': "
. $e->getMessage(), E_USER_WARNING);
}
}
}
echo $dom->saveHTML();
注意,对于PHP版本5.6.1和更新,你不需要明确创建DOMText情况下,因为DOMNode::textContent属性可供读取和写入。所以你可以简单地通过给这个属性赋一个字符串值来修改文本。只确保节点除XML_TEXT_NODE之外没有子节点。
上述检查的代码,如果trim($child->textContent)不为空,因为文档可以包含额外的空间字符(包括换行),例如:
text