您可以按照@04FS 的建议使用以下递归函数:
function replaceText(DOMNode $node, string $search, string $replace) {
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) {
$child->textContent = str_replace($search, $replace, $child->textContent);
} else {
replaceText($child, $search, $replace);
}
}
}
}
由于DOMDocument 也是DOMNode,所以您可以直接将其用作函数参数:
$html =
'<div class="foo">
<span class="foo">foo</span>
<span class="foo">foo</span>
foo
</div>';
$doc = new DOMDocument();
$doc->loadXML($html); // alternatively loadHTML(), will throw an error on invalid HTML tags
replaceText($doc, 'foo', 'bar');
echo $doc->saveXML();
// or
echo $doc->saveXML($doc->firstChild);
// ... to get rid of the leading XML version tag
会输出
<div class="foo">
<span class="foo">bar</span>
<span class="foo">bar</span>
bar
</div>
奖励:当您想要 str_replace 属性值时
function replaceTextInAttribute(DOMNode $node, string $attribute_name, string $search, string $replace) {
if ($node->hasAttributes()) {
foreach ($node->attributes as $attr) {
if($attr->nodeName === $attribute_name) {
$attr->nodeValue = str_replace($search, $replace, $attr->nodeValue);
}
}
}
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
replaceTextInAttribute($child, $attribute_name, $search, $replace);
}
}
}
奖励 2: 使功能更具可扩展性
function modifyText(DOMNode $node, callable $userFunc) {
if($node->hasChildNodes()) {
foreach($node->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) {
$child->textContent = $userFunc($child->textContent);
} else {
modifyText($child, $userFunc);
}
}
}
}
modifyText(
$doc,
function(string $string) {
return strtoupper(str_replace('foo', 'bar', $string));
}
);
echo $doc->saveXML($doc->firstChild);
会输出
<div class="foo">
<span class="foo">BAR</span>
<span class="foo">BAR</span>
BAR
</div>