我按如下方式加载DOMDocument:
$dom->loadHtml($str_html_fragment, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
额外的参数确保saveHTML
只输出片段,并且不会添加周围的doctypes或html标签。
$str_html_fragment
可能是
<ul>
<li>one</li>
<li>two</li>
</ul>
或
<span>one</span>
<span>two</span>
如果片段中已经存在单个根元素(如<ul
&gt;),我想为其添加一个类,但如果片段由多个兄弟节点组成,我想要使用新的<div>
围绕片段并将新类添加到该片段中,以提供:
<ul class="new-class">
<li>one</li>
<li>two</li>
</ul>
或
<div class="new-class">
<span>one</span>
<span>two</span>
</div>
通过查看文档,我无法确定如何计算是否有多个元素位于最高级别&#39;是否,或者在调用loadHTML
后如何添加周围的根元素。任何帮助表示赞赏。
答案 0 :(得分:1)
问题的描述和php.net的解决方案:
保存使用LIBXML_HTML_NOIMPLIED选项启动的HTML片段时, 它会最终被“破坏”,因为libxml需要root元素。的libxml 将尝试通过在末尾添加结束标记来修复片段 字符串基于它在片段中遇到的第一个打开的标记。
举个例子:
<h1>Foo</h1><p>bar</p>
将最终成为:
<h1>Foo<p>bar</p></h1>
最简单的解决方法是自己添加root标记并在以后剥离它:
$ html-&gt; loadHTML(''。$ content。'',LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$ content = str_replace(array('',''),'', $ HTML-&GT; saveHTML()方法);
当我将此应用于您的案例时,我最终得到以下代码,可以作为概念证明:
<?php
$dom = new DOMDocument;
$str_html_fragment = <<<'EOD'
<span>one</span>
<span>two</span>
EOD;
$dom->loadHTML('<html>' . $str_html_fragment .'</html>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$i = 0;
foreach($dom->childNodes as $top) {
foreach($top->childNodes as $node) {
echo "Node type is " . $node->nodeType . "\n";
if($node->nodeType == XML_ELEMENT_NODE) $i += 1;
}
}
echo "We have $i element nodes\n";
echo str_replace(array('<html>','</html>') , '' , $dom->saveHTML());
?>
此代码生成以下输出:
Node type is 1
Node type is 3
Node type is 1
We have 2 element nodes
<span>one</span>
<span>two</span>