如何删除DOM元素标签,但保留其内容? [英] How can I remove DOM element tags but leave their contents?

查看:382
本文介绍了如何删除DOM元素标签,但保留其内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有PHP代码可以删除至少有一个属性的所有节点。 这里是我的代码:

 <?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>

https://3v4l.org/9qHRM



(我添加了一些嵌套元素来展示这种方法的安全性。)






几个旁边:




  • 你不需要 $ 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>

https://3v4l.org/9qHRM

(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 additional LIBXML_HTML_NODEFDTD flag.
  • Your xpath expression can be simplified to //*[@*]

这篇关于如何删除DOM元素标签,但保留其内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆