我需要删除HTML文档中的一些标记(例如<div></div>
)并保留内部标记和文本。
我设法用Simple HTML Dom Parser做到了。但由于存储器需求巨大,它无法处理大文件。
我更喜欢使用像DOMDocument这样的原生PHP工具,因为我读到它在处理HTML文档时更加优化和快捷。
但是我在第一阶段挣扎 - 如何在保留内部文本和标签的同时删除一些标签。
源HTML示例是:
<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>
我试试这段代码:
$htmltext='<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>';
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML($htmltext);
$oldnodes = $doc->getElementsByTagName('div');
foreach ($oldnodes as $node) {
$fragment = $doc->createDocumentFragment();
while($node->childNodes->length > 0) {
$fragment->appendChild($node->childNodes->item(0));
}
$node->parentNode->replaceChild($fragment, $node);
}
echo $doc->saveHTML();
它产生输出:
<html><body>00000aaaaa<div>bbbbbbccc<a>link</a>cccdddddd</div>eeeee<div>1111</div></body></html>
我需要以下内容:
<html><body>00000aaaaabbbbbbccc<a>link</a>cccddddddeeeee1111</body></html>
有人可以帮我解决任务的正确代码吗?
答案 0 :(得分:1)
您可以在PHP中使用strip_tags函数。
$thmltext = '<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>';
strip_tags($htmltext, '<html>,<body>,<a>');
除去 html,body,a
之外,删除所有标签输出是:
<html><body>00000aaaaabbbbbbccc<a>link</a>cccddddddeeeee1111</body></html>
修改强> 如果是来自用户的输入,出于安全原因使用白名单标签而不是黑名单会更好。
答案 1 :(得分:0)
如果您的代码只包含没有任何属性的简单HTML标记,则可以保持简单,如:
$value = '<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>';
$pattern = '/<[\/]*(div|h1)>/';
$removedTags = preg_replace($pattern, '', $value);
由于您在评论中写道,除了要删除的div标签之外,我还在模式中添加了一个h1标签,以防您想要删除h1标签。
此代码段仅适用于简单代码,但适合您的HTML输入和输出示例。
答案 2 :(得分:0)
试试这个.. 只需使用以下代码替换for循环即可。
foreach ($oldnodes as $node) {
$children = $node->childNodes;
$string = "";
foreach($children as $child) {
$childString = $doc->saveXML($child);
$string = $string."".$childString;
}
$fragment = $doc->createDocumentFragment();
$fragment->appendXML($string);
$node->parentNode->insertBefore($fragment,$node);
$node->parentNode->removeChild($node);
}
答案 3 :(得分:0)
我找到了让它发挥作用的方法。 有问题的原因代码是在nodelist ruin nodelist中使用节点进行操作。所以“foreach”函数只通过nodelist中的4个项目中的2个 - 其余2个变得扭曲。
所以我只需要处理列表的第一个元素,然后重建列表,直到列表中有一些项目为止。
代码是:
$htmltext='<html><body><div>00000</div>aaaaa<div>bbbbbb<div>ccc<a>link</a>ccc</div>dddddd</div>eeeee<div>1111</div></body></html>';
echo "<!--
".$htmltext."
-->
";
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML($htmltext);
$oldnodes = $doc->getElementsByTagName('div');
while ($oldnodes->length>0){
$node=$oldnodes->item(0);
$fragment = $doc->createDocumentFragment();
while($node->childNodes->length > 0) {
$fragment->appendChild($node->childNodes->item(0));
}
$node->parentNode->replaceChild($fragment, $node);
$oldnodes = $doc->getElementsByTagName('div');
}
echo $doc->saveHTML();
我希望这会对遇到同样困难的人有所帮助。