PHP-DOMDocument-基于类删除文本周围的标记

PHP-DOMDocument-基于类删除文本周围的标记,php,html,domdocument,Php,Html,Domdocument,我有一个HTML文档,我想从中删除由特定类标识的特定标记。标记有多个类。我有一个非常简单的标记示例: <style>.c{background-color:yellow}</style> This is a <span class="a b c">string</span>. This is <span class="a b c">another string</span>. This is <span cla

我有一个HTML文档,我想从中删除由特定类标识的特定标记。标记有多个类。我有一个非常简单的标记示例:

<style>.c{background-color:yellow}</style>
This is a <span class="a b c">string</span>.  
This is <span class="a b c">another string</span>.  
This is <span class="a b">yet another string</span>.
基本上,我希望删除文本周围的标记,但保留文档上的文本

更新:我想我很接近了,但这对我不起作用:

$test = '<style>.c {background-color:yellow;}</style>' .
'This is a <span class="a b c">string</span>.'.
'This is <span class="a b c">another string</span>.' .
'This is <span class="a b">yet another string</span>.';

$doc = new DOMDocument();
$doc->loadHTML($test);
$xpath = new DOMXPath($doc);
$query = "//span[contains(@class, 'c')]"; // thanks to Gordon
$oldnodes = $xpath->query($query);

foreach ($oldnodes as $oldnode) {
    $txt = $oldnode->nodeValue;
    $oldnode->parentNode->replaceChild($txt, $oldnode);
}

echo $doc->saveHTML();
$test='.c{背景色:黄色;}'。
“这是一根绳子。”。
“这是另一根弦。”。
“这是另一根弦。”;
$doc=新的DOMDocument();
$doc->loadHTML($test);
$xpath=新的DOMXPath($doc);
$query=“//span[包含(@class,'c')]”;//多亏了戈登
$oldnodes=$xpath->query($query);
foreach($oldnodes作为$oldnode){
$txt=$oldnode->nodeValue;
$oldnode->parentNode->replaceChild($txt,$oldnode);
}
echo$doc->saveHTML();

你很接近。。。为子对象创建一个片段:

$query = "//span[contains(concat(' ', normalize-space(@class), ' '), ' c ')]";
$oldnodes = $xpath->query($query);

foreach ($oldnodes as $node) {
    $fragment = $doc->createDocumentFragment();
    while($node->childNodes->length > 0) {
        $fragment->appendChild($node->childNodes->item(0));
    }
    $node->parentNode->replaceChild($fragment, $node);
}
由于每次迭代都将删除
$node
,因此无需迭代(由于不再有效,它将从结果集中动态删除它)

这也将处理范围内不只是文本的情况:

<span class="a b c">foo <b>bar</b> baz</span>
foobarbaz
注意最近的编辑:我将xpath查询更改为更加健壮,因为现在它将只匹配精确的类
c
,而不是
toc


奇怪的是,它允许您在迭代中删除,而不影响结果(我知道以前已经这样做了,我只是不知道为什么在这里)。但是这是经过测试的代码,应该是好的。

周五的时候脑子太笨了,无法拿出实际的代码,但是一点明智的XPath和.innerTEXT应该可以让您继续。找到所有具有“C类”的节点,并用其自己的innerTEXTGordon替换该节点:谢谢你的提示,让我更新我的代码。。。现在我只想知道如何移除标签。谢谢你的提示。。。但是,我得到了以下结果:致命错误:调用未定义的方法DOMNodeList::valid()@James:fixed。抱歉,我遗漏了一些内容(并且错误地认为DomNodeList是迭代器)。试试这个……谢谢。。。现在我得到了这个错误:致命错误:在非-object@James:当有子标签时,我刚刚修复了另一个bug(谢谢@Gordon)…没问题。将删除我的答案,因为这真的有它需要知道的一切。
<span class="a b c">foo <b>bar</b> baz</span>