PHP DOMDocument解析TinyMCE HTML时hr标签后内容丢失求助
解决DOMDocument解析HR后丢失内容的问题
我刚好碰到过类似的坑,其实问题出在你使用的LIBXML_HTML_NOIMPLIED和LIBXML_HTML_NODEFDTD这两个参数上,我来给你拆解清楚:
为什么会丢失后续内容?
当你添加这两个参数时,DOMDocument不会自动给你的HTML补全<html>和<body>根元素。这时候你的输入<hr /><p> </p><p>test input</p>会被解析成三个同级的顶级节点(<hr>、<p>、<p>)。而默认调用saveHTML()不传参数时,它只会输出文档的第一个子节点,所以后面的内容就被忽略了。
你可以验证一下文档结构:
$input = '<hr /><p> </p><p>test input</p>'; $domDoc = new DOMDocument(); $domDoc->loadHTML($input, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 打印所有子节点数量 var_dump($domDoc->childNodes->length); // 输出int(3),说明三个节点都存在
两种解决方案
方案1:手动添加根容器包裹内容
给输入套一个<div>(或其他容器),确保文档有唯一的根节点,这样所有内容都会被包含进去:
$input = '<hr /><p> </p><p>test input</p>'; // 用div包裹原始内容 $wrappedInput = '<div>' . $input . '</div>'; $domDoc = new DOMDocument(); $domDoc->loadHTML($wrappedInput, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // 获取div内部的所有内容 $content = $domDoc->saveHTML($domDoc->documentElement->firstChild); var_dump($content); // 输出结果:<hr><p> </p><p>test input</p>
方案2:遍历所有顶级节点拼接输出
如果不想添加额外的容器,可以直接遍历文档的所有子节点,逐个调用saveHTML()并拼接结果:
$input = '<hr /><p> </p><p>test input</p>'; $domDoc = new DOMDocument(); $domDoc->loadHTML($input, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $output = ''; // 遍历每个顶级节点并保存 foreach ($domDoc->childNodes as $node) { $output .= $domDoc->saveHTML($node); } var_dump($output); // 输出结果:<hr><p> </p><p>test input</p>
补充说明
DOMDocument会自动把自闭合的<hr />转换成<hr>,这是HTML标准的序列化行为,完全不影响页面渲染和功能,不用在意这个差异。
内容的提问来源于stack exchange,提问作者user7968630
相关产品推荐
相关产品推荐

