DOMElement 替换 HTML 值

Posted

技术标签:

【中文标题】DOMElement 替换 HTML 值【英文标题】:DOMElement replace HTML value 【发布时间】:2016-10-24 04:18:56 【问题描述】:

我在 DOMElement 中有这个 html 字符串:

<h1>Home</h1>
testtest

我想用一种方式替换这个内容,只有

<h1>Home</h1>
test

保留(所以我想删除test)。

此时,我的代码如下所示:

$node->nodeValue = preg_replace(
    '/(?<replaceable>([a-z0-9_]+))/mi', '' , $node->nodeValue);

这不起作用,因为nodeValue 不包含节点的 HTML 值。 除了使用$node-&gt;C14N()之外,我无法弄清楚如何获取节点的HTML字符串,但是使用C14N我无法替换内容。 有什么想法可以在这样的 HTML 字符串中删除 test 吗?

【问题讨论】:

【参考方案1】:

您尝试过DOMDocument::saveXML 功能吗? (http://php.net/manual/en/domdocument.savexml.php)

它有第二个参数$node,您可以使用它指定打印 HTML/XML 的节点。

所以,例如:

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('body');
$root = $doc->appendChild($root);

$title = $doc->createElement('h1', 'Home');
$root->appendChild($title);

$text = $doc->createTextNode('testtest');
$text = $root->appendChild($text);

echo $doc->saveXML($root);

?>

这会给你:

<body>
  <h1>Home</h1>
  testtest
</body>

如果你不想要&lt;body&gt; 标签,你可以循环遍历它的所有子节点:

<?php

foreach($root->childNodes as $child)    
    echo $doc->saveXML($child);


?>

这会给你:

<h1>Home</h1>testtest

编辑:你当然可以用你已经在使用的正则表达式替换test

<?php

$xml = '';
foreach($root->childNodes as $child)    
    $xml .= preg_replace(
                '/(?<replaceable>([a-z0-9_]+))/mi', '', 
                $doc->saveXML($child)
    );


?>

这会给你:

<h1>Home</h1>test

注意:我还没有测试过代码,但这应该会给你大致的想法。

【讨论】:

【参考方案2】:

问题主要在于您如何浏览 DOM,但您的 RegExp 也存在问题; XPath 实际上在 DOM 操作方面提供了很大的灵活性,因此这是我的首选解决方案。

假设你有一个这样构建的 DOMDocument(我附上了一个 XPath):

$dom = new DOMDocument('1.0', 'utf-8');
$xpath = new DOMXPath($dom);

$node = $dom->createElement('div');
$node->appendChild(
    $dom->createElement('h1', "Home")
    );
$node->appendChild(
    $dom->createTextNode("testtest")
    );

$dom->appendChild($node);

您可以在 XPath 中使用 '/div/text()' 专门针对该 &lt;div&gt; 的文本节点。

所以要在该文本节点中替换 test 而不会破坏节点的其余部分,您可以这样做:

$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
        '/(.*)[^]+/m', 
        '$1',
        $xpath->query('/div/text()')->item(0)->nodeValue
);

有点复杂,但$dom-&gt;saveXML(); 的输出是:

<?xml version="1.0" encoding="utf-8"?>
<div><h1>Home</h1>test</div>

test 已被删除,其余部分完好无损。

【讨论】:

我目前只有 DOMElement 节点可用,不能使用 dom 或 xpath。或者我也应该将孩子加载为 xpath。 您可以将节点加载到一个带有“组成”root 节点的 DOMDocument 中 - 然后在您完成操作后提取原始元素。

以上是关于DOMElement 替换 HTML 值的主要内容,如果未能解决你的问题,请参考以下文章

模块“domhandler”没有导出的成员“DomElement”。您的意思是改用“从“domhandler”导入 DomElement”吗?

如何获取 DomElement 的字符串?

PHP:DomElement->getAttribute

有没有办法获取 DOMElement 的所有属性?

DOMElement 类的对象无法转换为字符串

text str2DOMElement