在PHP中删除具有某个类的DomNode

时间:2012-10-15 20:28:27

标签: php dom

我有一个HTML文档(字符串),其中包含一个带有“foo”类的div:

<html>
<head>
  ...
</head>
<body>
<div class="whatever">Blabla</div>
<div>
   <span>Text</span>
</div>
<table>
   <tr><td><div class="foo">GARBAGE</div></td></tr>
</table>
</body>

我只想删除所有带有“foo”类的div,这是我到目前为止所拥有的:

$doc = new DOMDocument();
$doc->loadHTML($myhtml);
$xpath = new DOMXpath($doc);
$all = $xpath->query("/html");

$result = remove_elements_with_class('foo', $all);

remove_elements_with_class函数的外观如何?

1 个答案:

答案 0 :(得分:4)

后:

$xpath = new DOMXpath($doc);

你需要:

  1. 选择要删除的所有节点
  2. 在这些节点上调用DOMNode::removeChild()
  3. 因此,要完成第一项任务,您可以发出一个XPath查询,查找其类为<div>的所有foo个节点。该查询看起来像:

    //div[contains(concat(' ', @class, ' '), ' foo ')]
    

    请注意,这会处理元素可以包含多个类的情况,即foo bar bazbaz foo bar。如果这是不合需要的,并且您只想完全匹配该类(因此现在只有完全foo的类匹配),查询将变为:

    //div[@class = 'foo']
    

    而且,在PHP中,这变为:

    $nodes = $xpath->query( "//div[contains(concat(' ', @class, ' '), ' foo ')]");
    

    从这里开始,您要在$nodes中删除所有要删除的节点,因此只需迭代它们,然后通过抓取<div>的父节点将其从文档中删除,然后删除它子节点:

    foreach( $nodes as $node) {
        $node->parentNode->removeChild( $node);
    }
    

    这就是全部!您可以在this demo中看到它正常工作。

    修改:要保留<div>并删除内容,请将节点的nodeValue属性设置为空字符串:

    foreach( $nodes as $node) {
        $node->nodeValue = '';
    }
    

    您可以在this updated demo中看到它正常工作。您也可以用新创建的<div>替换<div>,因为这种方法似乎更具防弹性,但这应该适用于您的用例。