DOMElement 替换 HTML 值
DOMElement replace HTML value
我在 DOMElement
中有这个 HTML 字符串:
<h1>Home</h1>
test{{test}}
我想以仅
的方式替换此内容
<h1>Home</h1>
test
仍然存在(所以我想删除 {{test}}
)。
此刻,我的代码是这样的:
$node->nodeValue = preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '' , $node->nodeValue);
这不起作用,因为 nodeValue
不包含节点的 HTML 值。
除了使用 $node->C14N()
之外,我不知道如何获取节点的 HTML 字符串,但是通过使用 C14N
我无法替换内容。
我有什么想法可以像这样删除 HTML 字符串中的 {{test}}
吗?
你试过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('test{{test}}');
$text = $root->appendChild($text);
echo $doc->saveXML($root);
?>
这会给你:
<body>
<h1>Home</h1>
test{{test}}
</body>
如果您不想要 <body>
标签,您可以循环遍历它的所有子节点:
<?php
foreach($root->childNodes as $child){
echo $doc->saveXML($child);
}
?>
这会给你:
<h1>Home</h1>test{{test}}
编辑:您当然可以用您已经在使用的正则表达式替换 {{test}}
:
<?php
$xml = '';
foreach($root->childNodes as $child){
$xml .= preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '',
$doc->saveXML($child)
);
}
?>
这会给你:
<h1>Home</h1>test
注意:我还没有测试代码,但这应该能给你大概的想法。
问题主要在于您如何导航 DOM,但您的 RegExp 也有问题;在 DOM 操作方面,XPath 实际上提供了很大的灵活性,因此这是我的首选解决方案。
假设您有一个 DOM这样构建的文档(我附加了一个 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("test{{test}}")
);
$dom->appendChild($node);
您可以在 XPath 中使用 '/div/text()'
专门针对 <div>
的文本节点。
因此,要在该文本节点内替换 {{test}}
而不破坏节点的其余部分,您可以这样做:
$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
'/(.*){{[^}]+}}/m',
'',
$xpath->query('/div/text()')->item(0)->nodeValue
);
有点复杂,但 $dom->saveXML();
的输出是:
<?xml version="1.0" encoding="utf-8"?>
<div><h1>Home</h1>test</div>
{{test}}
已删除,其余部分完好无损。
我在 DOMElement
中有这个 HTML 字符串:
<h1>Home</h1>
test{{test}}
我想以仅
的方式替换此内容<h1>Home</h1>
test
仍然存在(所以我想删除 {{test}}
)。
此刻,我的代码是这样的:
$node->nodeValue = preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '' , $node->nodeValue);
这不起作用,因为 nodeValue
不包含节点的 HTML 值。
除了使用 $node->C14N()
之外,我不知道如何获取节点的 HTML 字符串,但是通过使用 C14N
我无法替换内容。
我有什么想法可以像这样删除 HTML 字符串中的 {{test}}
吗?
你试过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('test{{test}}');
$text = $root->appendChild($text);
echo $doc->saveXML($root);
?>
这会给你:
<body>
<h1>Home</h1>
test{{test}}
</body>
如果您不想要 <body>
标签,您可以循环遍历它的所有子节点:
<?php
foreach($root->childNodes as $child){
echo $doc->saveXML($child);
}
?>
这会给你:
<h1>Home</h1>test{{test}}
编辑:您当然可以用您已经在使用的正则表达式替换 {{test}}
:
<?php
$xml = '';
foreach($root->childNodes as $child){
$xml .= preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '',
$doc->saveXML($child)
);
}
?>
这会给你:
<h1>Home</h1>test
注意:我还没有测试代码,但这应该能给你大概的想法。
问题主要在于您如何导航 DOM,但您的 RegExp 也有问题;在 DOM 操作方面,XPath 实际上提供了很大的灵活性,因此这是我的首选解决方案。
假设您有一个 DOM这样构建的文档(我附加了一个 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("test{{test}}")
);
$dom->appendChild($node);
您可以在 XPath 中使用 '/div/text()'
专门针对 <div>
的文本节点。
因此,要在该文本节点内替换 {{test}}
而不破坏节点的其余部分,您可以这样做:
$xpath->query('/div/text()')->item(0)->nodeValue = preg_replace(
'/(.*){{[^}]+}}/m',
'',
$xpath->query('/div/text()')->item(0)->nodeValue
);
有点复杂,但 $dom->saveXML();
的输出是:
<?xml version="1.0" encoding="utf-8"?>
<div><h1>Home</h1>test</div>
{{test}}
已删除,其余部分完好无损。