Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php DOMDocument,添加周围环境<;部门>;如果需要_Php_Html_Domdocument - Fatal编程技术网

Php DOMDocument,添加周围环境<;部门>;如果需要

Php DOMDocument,添加周围环境<;部门>;如果需要,php,html,domdocument,Php,Html,Domdocument,我正在加载一个DOM文档,如下所示: $dom->loadHtml($str_html_fragment, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 额外的参数确保saveHTML只输出片段,而不添加周围的doctype或html标记 $str\u html\u片段可以是 <ul> <li>one</li> <li>two</li> </ul> 一个 两

我正在加载一个DOM文档,如下所示:

$dom->loadHtml($str_html_fragment, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
额外的参数确保
saveHTML
只输出片段,而不添加周围的doctype或html标记

$str\u html\u片段
可以是

<ul>
  <li>one</li>
  <li>two</li>
</ul>
  • 一个
  • 两个

1
二
如果片段中已经有一个根元素(如
),我想向其添加一个类,但如果片段由多个同级节点组成,我想用一个新的
包围片段,并将新类添加到该片段中,以给出:

<ul class="new-class">
  <li>one</li>
  <li>two</li>
</ul>
  • 一个
  • 两个


一
二

通过查看文档,我看不到如何计算是否有多个元素处于“顶层”,或者如何在调用
loadHTML
后添加周围的根元素。非常感谢您的帮助。

以下是问题描述和解决方案:

保存用LIBXML\u HTML\u NOIMPLIED选项启动的HTML片段时, 由于libxml需要根元素,它最终将被“破坏”。libxml 将尝试通过在结尾添加结束标记来修复片段 基于片段中遇到的第一个打开标记的字符串

例如:

Foobar

最终将成为:

Foobar

最简单的解决方法是自己添加根标记,然后将其剥离:

$html->loadHTML('.$content'',LIBXML\u html\u noimpled |LIBXML_HTML_NODEFDTD)

$content=str_replace(数组('',''),'', $html->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>
节点类型为1
节点类型为3
节点类型为1
我们有两个元素节点
一
二

如果您这样做
echo$dom->saveHTML()在第二个示例中(两个span元素-你实际上得到了两个
onetwo
,这无论如何都是行不通的-我想。你为什么不每次都用你的
?那么你甚至不需要操纵DOM。你只需要
$html=sprintf('%s','newclass',$html)
@NigelRen Thank不知道这一点-当时正试图进行防御性编写,实际上还没有遇到我自己的两个跨度的测试场景:(我的bad@ChristopheDeliens问题是额外的可能会扰乱布局或改变CSS规则的效果(对于2跨的情况来说,这仍然是一个危险因素,但添加周围类别更为重要)
<?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>