DOMDocument,如果需要,添加周围的<div>

时间:2017-12-14 13:34:01

标签: php html domdocument

我按如下方式加载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后如何添加周围的根元素。任何帮助表示赞赏。

1 个答案:

答案 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>