0

クラス「foo」のdivを含むHTMLドキュメント(文字列)があります:

<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関数はどのように見えますか?

4

1 に答える 1

4

後:

$xpath = new DOMXpath($doc);

必要がある:

  1. 削除するすべてのノードを選択します
  2. DOMNode::removeChild()それらのノードを呼び出す

したがって、最初のタスクを実行するために、<div>クラスが。であるすべてのノードを検索するXPathクエリを発行できますfoo。そのクエリは次のようになります。

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

これは、要素が複数のクラス、つまりfoo bar bazとを含むことができる場合を処理することに注意してくださいbaz 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);
}

必要なのはそれだけです!このデモでそれが機能しているのを見ることができます。

編集:コンテンツを保持して<div>削除するには、ノードのnodeValue属性を空の文字列に設定します。

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

この更新されたデモでそれが機能しているのを見ることができます。<div>を新しく作成したものに置き換えることもでき<div>ます。これは、そのアプローチの方が防弾のように見えるためですが、これはユースケースで機能するはずです。

于 2012-10-15T20:38:51.873 に答える