使用带有html片段的LIB
XML_HTML_NOIMPLIED标志会生成不正确的标签:
$str = '<p>Lorem ipsum dolor sit amet.</p><p>Nunc vel vehicula ante.</p>'; $doc = new DOMDocument(); $doc->loadHTML($str,LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); echo $doc->saveHTML();
输出:
<p>Lorem ipsum dolor sit amet.<p>Nunc vel vehicula ante.</p></p>
我发现使用正则表达式来解决这个问题,但是这破坏了使用DOM的目的.我已经测试了几个版本的libxml和PHP,最新的libxml 2.9.2,PHP 5.6.7(Debian Jessy).任何建议赞赏.
解决方法
重新安排由您使用的LIBXML_HTML_NOIMPLIED选项完成.看起来它对你的情况不够稳定.
另外你可能不想使用它的portablility的原因,例如,我有一个PHP 5.4.36与Libxml 2.7.8在手不支持LIBXML_HTML_NOIMPLIED(Libxml> = 2.7.7),但后来LIBXML_HTML_NODEFDTD(Libxml> ; = 2.7.8)选项.
我知道这种处理方式.加载片段时,将其包装成< div>元件:
$doc->loadHTML("<div>$str</div>");
这有助于指导您想要的结构的DOMDocument.
然后,您可以从文档本身中提取此容器:
$container = $doc->getElementsByTagName('div')->item(0); $container = $container->parentNode->removeChild($container);
然后从文档中删除所有的孩子:
while ($doc->firstChild) { $doc->removeChild($doc->firstChild); }
现在这个文件是完全空的,你现在可以再次追加孩子了.幸运的是有< div>容器元素我们之前删除,所以我们可以从中添加:
while ($container->firstChild ) { $doc->appendChild($container->firstChild); }
然后可以使用已知的saveHTML方法检索片段
echo $doc->saveHTML();
哪一个在你的情况下呢?
<p>Lorem ipsum dolor sit amet.</p><p>Nunc vel vehicula ante.</p>
这种方法与现场的现有材料有些不同(见下文给出的参考资料),所以这个例子是一次:
$str = '<p>Lorem ipsum dolor sit amet.</p><p>Nunc vel vehicula ante.</p>'; $doc = new DOMDocument(); $doc->loadHTML("<div>$str</div>"); $container = $doc->getElementsByTagName('div')->item(0); $container = $container->parentNode->removeChild($container); while ($doc->firstChild) { $doc->removeChild($doc->firstChild); } while ($container->firstChild ) { $doc->appendChild($container->firstChild); } echo $doc->saveHTML();
我还真的推荐了关于如何保存DOMDocumentHTML而不使用HTML包装的参考问题?进一步阅读以及关于inner-html的内容
参考
> How to saveHTML of DOMDocument without HTML wrapper?
> How to get innerHTML of DOMNode?