html片段上的php-loadHTML LIBXML_HTML_NOIMPLIED会生成不正确的标签

使用带有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?

相关文章

Mip是什么意思以及作用有哪些
怎么测试Mip页面运行情况
MIP安装的具体步骤有哪些
HTML添加超链接、锚点的方法及作用详解(附视频)
MIP的规则有哪些
Mip轮播图组件中的重要属性讲解