我在使用 PHP 解析 HTML 时遇到问题DOM文档.
我正在解析的 HMTL 有以下内容脚本标签:
<script type="text/javascript">
var showShareBarUI_params_e81 =
{
buttonWithCountTemplate: '<div class="sBtnWrap"><a href="#" onclick="$onClick"><div class="sBtn">$text<img src="$iconImg" /></div><div class="sCountBox">$count</div></a></div>',
}
</script>
这段代码有两个问题:
1) 里面的HTMLbuttonWithCountTemplate
var 没有转义。 DOMDocument 正确地管理它,在解析它时转义字符。不是问题。
2)接近尾声时,有一个带有未转义结束标签的 img 标签:
<img src="$iconImg" />
The />
使 DOMDocument 认为脚本已完成,但是它缺少结束标签。如果您使用 getElementByTagName 提取脚本,您将在此 img 标记处关闭标记,其余部分将出现作为 HTML 上的文本.
我的目标是删除此页面中的所有脚本,因此如果我执行removeChild()
在此标签上,该标签将被删除,但渲染页面时以下部分将显示为文本:
</div><div class="sCountBox">$count</div></a></div>',
}
</script>
修复 HTML 不是一个解决方案,因为我正在开发一个通用解析器并且需要处理所有类型的 HTML。
我的问题是,在将 HTML 提供给 DOMDocument 之前是否应该进行任何清理,或者是否有一个在 DOMDocument 上启用的选项以避免触发此问题,或者即使我可以在加载 HTML 之前删除所有标签。
有任何想法吗?
EDIT
经过一番研究,我发现了 DOMDocument 解析器的真正问题。考虑以下 HTML:
<div> <!-- Offending div without closing tag -->
<script type="text/javascript">
var test = '</div>';
// I should not appear on the result
</script>
使用以下 php 代码删除脚本标签(基于 Gholizadeh 的回答 https://stackoverflow.com/a/40762772/1371474):
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
libxml_use_internal_errors(true);
$dom->loadHTML(file_get_contents('js.html'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
//@$dom->loadHTMLFile('script.html'); //fix tags if not exist
while($nodes = $dom->getElementsByTagName("script")) {
if($nodes->length == 0) break;
$script = $nodes->item(0);
$script->parentNode->removeChild($script);
}
//return $dom->saveHTML();
$final = $dom->saveHTML();
echo $final;
结果如下:
<div> <!-- Offending div without closing tag -->
<p>';
// I should not appear on the result
</p></div>
问题是第一个 div 标签没有关闭,并且 DOMDocument 似乎将 JS 字符串内的 div 标签视为 html 而不是简单的 JS 字符串。
我可以做什么来解决这个问题?请记住,修改 HTML 不是一个选项,因为我正在开发一个通用解析器。