DOMDocument,如果需要,添加周围的 <div>
DOMDocument, adding surrounding <div> if needed
我正在按如下方式加载 DOMDocument:
$dom->loadHtml($str_html_fragment, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
额外的参数确保 saveHTML
只输出片段,而不添加周围的文档类型或 html 标签。
$str_html_fragment
可以是
<ul>
<li>one</li>
<li>two</li>
</ul>
或
<span>one</span>
<span>two</span>
如果片段中已经有一个根元素(如 <ul
>),我想向其添加一个 class,但如果片段由多个同级元素组成节点,我想用新的 <div>
围绕片段并向其添加新的 class,以给出:
<ul class="new-class">
<li>one</li>
<li>two</li>
</ul>
或
<div class="new-class">
<span>one</span>
<span>two</span>
</div>
通过查看文档,我看不到如何计算 'top level' 处是否有多个元素,或者如何在 loadHTML
之后添加周围的根元素叫。任何帮助表示赞赏。
php.net 中有问题描述和解决方案:
When saving HTML fragment initiated with LIBXML_HTML_NOIMPLIED option,
it will end up being "broken" as libxml requires root element. libxml
will attempt to fix the fragment by adding closing tag at the end of
string based on the first opened tag it encounters in the fragment.
For an example:
<h1>Foo</h1><p>bar</p>
will end up as:
<h1>Foo<p>bar</p></h1>
Easiest workaround is adding root tag yourself and stripping it later:
$html->loadHTML('' . $content .'', LIBXML_HTML_NOIMPLIED
| LIBXML_HTML_NODEFDTD);
$content = str_replace(array('','') , '' ,
$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>
我正在按如下方式加载 DOMDocument:
$dom->loadHtml($str_html_fragment, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
额外的参数确保 saveHTML
只输出片段,而不添加周围的文档类型或 html 标签。
$str_html_fragment
可以是
<ul>
<li>one</li>
<li>two</li>
</ul>
或
<span>one</span>
<span>two</span>
如果片段中已经有一个根元素(如 <ul
>),我想向其添加一个 class,但如果片段由多个同级元素组成节点,我想用新的 <div>
围绕片段并向其添加新的 class,以给出:
<ul class="new-class">
<li>one</li>
<li>two</li>
</ul>
或
<div class="new-class">
<span>one</span>
<span>two</span>
</div>
通过查看文档,我看不到如何计算 'top level' 处是否有多个元素,或者如何在 loadHTML
之后添加周围的根元素叫。任何帮助表示赞赏。
php.net 中有问题描述和解决方案:
When saving HTML fragment initiated with LIBXML_HTML_NOIMPLIED option, it will end up being "broken" as libxml requires root element. libxml will attempt to fix the fragment by adding closing tag at the end of string based on the first opened tag it encounters in the fragment.
For an example:
<h1>Foo</h1><p>bar</p>
will end up as:
<h1>Foo<p>bar</p></h1>
Easiest workaround is adding root tag yourself and stripping it later:
$html->loadHTML('' . $content .'', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$content = str_replace(array('','') , '' , $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>