如何删除DOM元素标签,但保留其内容? [英] How can I remove DOM element tags but leave their contents?
本文介绍了如何删除DOM元素标签,但保留其内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
<?php
$ data =<<< DATA
< div>
< p>这些行将保持< / p>
< p class =myclass>删除此一个< / p>
< p>但是保持这个< / p>
< div style =color:red>和此< / div>
< / div>
DATA;
$ dom = new DOMDOcument();
$ dom-> loadHTML($ data,LIBXML_HTML_NOIMPLIED);
$ dom-> removeChild($ dom-> doctype);
$ xpath = new DOMXPath($ dom);
$ lines_to_be_removed = $ xpath-> query(// * [count(@ *)> 0]);
foreach($ lines_to_be_removed as $ line){
$ line-> parentNode-> removeChild($ line);
}
//只是为了检查
echo $ dom-> saveHTML();
?>
正如你在小提琴中看到的,这是上面代码的当前输出:
< div>
< p>这些行将保持< / p>
< p>但是保持这个< / p>
< / div>
虽然这是所需的结果:
< DIV>
< p>这些行将保持< / p>
删除这个
< p>但是保持这个< / p>
和这个
< / div>
我该怎么做?
示例:
在解除元素之前,您要删除其子节点并将其贴在后面。 > $ data =<<< DATA
< div>
< p>这些行将保持< / p>
< p class =myclass>删除此一个< / p>
< p>但是保持这个< / p>
< div style =color:red>和此< / div>
< div style =color:red>和< p>也< / p>该< / DIV>
< div style =color:red>,< div style =color:red>< / div>< / div>
< / div>
DATA;
$ dom = new DOMDocument();
$ dom-> loadHTML($ data,LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$ xpath = new DOMXPath($ dom);
foreach($ xpath-> query(// * [@ *])as $ node){
$ parent = $ node-> parentNode;
while($ node-> hasChildNodes()){
$ parent-> insertBefore($ node-> lastChild,$ node-> nextSibling);
}
$ parent-> removeChild($ node);
}
echo $ dom-> saveHTML();
输出:
code>< DIV>
< p>这些行将保持< / p>
删除这个
< p>但是保持这个< / p>
和
和< p>也< / p>这个
这个也是
< / div>
(我添加了一些嵌套元素来展示这种方法的安全性。)
几个旁边:
- 你不需要
$ dom-> removeChild($ dom-> doctype)
如果您使用附加的LIBXML_HTML_NODEFDTD
标志加载 - 您的xpath表达式可以简化为
// * [@ *]
I have PHP code which removes all nodes that have at least one attribute. Here is my code:
<?php
$data = <<<DATA
<div>
<p>These line shall stay</p>
<p class="myclass">Remove this one</p>
<p>But keep this</p>
<div style="color: red">and this</div>
</div>
DATA;
$dom = new DOMDOcument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED);
$dom->removeChild($dom->doctype);
$xpath = new DOMXPath($dom);
$lines_to_be_removed = $xpath->query("//*[count(@*)>0]");
foreach ($lines_to_be_removed as $line) {
$line->parentNode->removeChild($line);
}
// just to check
echo $dom->saveHTML();
?>
As you see in the fiddle, this is the current output of code above:
<div>
<p>These line shall stay</p>
<p>But keep this</p>
</div>
While this is desired result:
<div>
<p>These line shall stay</p>
Remove this one
<p>But keep this</p>
and this
</div>
How can I do that?
解决方案
Prior to removing the elements you want to pluck out their child nodes and tack them on behind it.
Example:
$data = <<<DATA
<div>
<p>These line shall stay</p>
<p class="myclass">Remove this one</p>
<p>But keep this</p>
<div style="color: red">and this</div>
<div style="color: red">and <p>also</p> this</div>
<div style="color: red">and this <div style="color: red">too</div></div>
</div>
DATA;
$dom = new DOMDocument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach ($xpath->query("//*[@*]") as $node) {
$parent = $node->parentNode;
while ($node->hasChildNodes()) {
$parent->insertBefore($node->lastChild, $node->nextSibling);
}
$parent->removeChild($node);
}
echo $dom->saveHTML();
Outputs:
<div>
<p>These line shall stay</p>
Remove this one
<p>But keep this</p>
and this
and <p>also</p> this
and this too
</div>
(I added some nested elements to demonstrate the safety of this approach.)
Couple of asides:
- You don't need
$dom->removeChild($dom->doctype)
if you load with the additionalLIBXML_HTML_NODEFDTD
flag. - Your xpath expression can be simplified to
//*[@*]
这篇关于如何删除DOM元素标签,但保留其内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文