PHP Dom删除元素保留内容

PHP Dom删除元素保留内容,php,html,dom,xpath,Php,Html,Dom,Xpath,我试图删除某些链接,这取决于它们的ID标签,但保留链接的内容。比如我想转身 Some text goes <a href="http://www.domain.tdl/" id="remove">here</a> 我试过使用下面的方法 $dom = new DOMDocument; $dom->loadHtml(mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8")); $xp = new DOMXPath($do

我试图删除某些链接,这取决于它们的ID标签,但保留链接的内容。比如我想转身

Some text goes <a href="http://www.domain.tdl/" id="remove">here</a>
我试过使用下面的方法

$dom = new DOMDocument;
$dom->loadHtml(mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8"));
$xp = new DOMXPath($dom);

foreach($xp->query('//a[contains(@id="remove")]') as $oldNode) {
$revised = strip_tags($oldNode);
}

$revised = mb_substr($dom->saveXML($xp->query('//body')->item(0)), 6, -7, "UTF-8");
echo $revised;
大致取自,但它只是吐回了
$html
的相同内容


有没有关于如何实现这一点的想法?

这是我的职责:

function DOMRemove(DOMNode $from) {
    $sibling = $from->firstChild;
    do {
        $next = $sibling->nextSibling;
        $from->parentNode->insertBefore($sibling, $from);
    } while ($sibling = $next);
    $from->parentNode->removeChild($from);    
}
因此:

$dom->loadHTML('Hello <a href="foo"><span>World</span></a>');
$a = $dom->getElementsByTagName('a')->item(0); // get first
DOMRemove($a);

这就是我的功能:

function DOMRemove(DOMNode $from) {
    $sibling = $from->firstChild;
    do {
        $next = $sibling->nextSibling;
        $from->parentNode->insertBefore($sibling, $from);
    } while ($sibling = $next);
    $from->parentNode->removeChild($from);    
}
因此:

$dom->loadHTML('Hello <a href="foo"><span>World</span></a>');
$a = $dom->getElementsByTagName('a')->item(0); // get first
DOMRemove($a);
使用

 //a[@id='remove']/node() 
| 
 //*[a[@id='remove']]/node()[not(self::a[@id=''remove])]
这将选择任何
a
具有属性
id
且值
为“remove”
的所有子级
a
,以及该
a
的所有前后同级
a
本身不是另一个
id
属性
且值
为“remove”
:

 //a[@id='remove']/node() 
| 
 //*[a[@id='remove']]/node()[not(self::a[@id=''remove])]

这将选择任何
a
具有属性
id
且值
为“remove”
的所有子级
a
,以及该
a
的所有前后同级
a
本身不是另一个
id
且值
为“remove”的
a

一种类似于@netcoder答案的方法,但使用不同的循环结构和domeElement方法

$html = '<html><body>This <a href="http://www.domain.tdl/" id="remove">link</a> was removed.</body></html>';
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//a[@id="remove"]') as $link) {
  // Move all link tag content to its parent node just before it.
  while($link->hasChildNodes()) {
    $child = $link->removeChild($link->firstChild);
    $link->parentNode->insertBefore($child, $link);
  }
  // Remove the link tag.
  $link->parentNode->removeChild($link);
}
$html = $dom->saveXML();
$html='这已被删除';
$dom=新的DOMDocument();
$dom->loadHTML($html);
$xpath=newdomxpath($dom);
foreach($xpath->query('//a[@id=“remove”]')作为$link){
//将所有链接标记内容移动到其前面的父节点。
而($link->hasChildNodes()){
$child=$link->removeChild($link->firstChild);
$link->parentNode->insertBefore($child,$link);
}
//移除链接标签。
$link->parentNode->removeChild($link);
}
$html=$dom->saveXML();

一种类似于@netcoder答案的方法,但使用不同的循环结构和DomeElement方法

$html = '<html><body>This <a href="http://www.domain.tdl/" id="remove">link</a> was removed.</body></html>';
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//a[@id="remove"]') as $link) {
  // Move all link tag content to its parent node just before it.
  while($link->hasChildNodes()) {
    $child = $link->removeChild($link->firstChild);
    $link->parentNode->insertBefore($child, $link);
  }
  // Remove the link tag.
  $link->parentNode->removeChild($link);
}
$html = $dom->saveXML();
$html='这已被删除';
$dom=新的DOMDocument();
$dom->loadHTML($html);
$xpath=newdomxpath($dom);
foreach($xpath->query('//a[@id=“remove”]')作为$link){
//将所有链接标记内容移动到其前面的父节点。
而($link->hasChildNodes()){
$child=$link->removeChild($link->firstChild);
$link->parentNode->insertBefore($child,$link);
}
//移除链接标签。
$link->parentNode->removeChild($link);
}
$html=$dom->saveXML();

您没有在此处修改您的文档,这就是它显示相同内容的原因。例如,您在DOM对象上提供了调用
replaceChild
,您只是创建了一个变量,稍后您将使用
saveXML
好问题+1的输出覆盖该变量。请参阅我对一个XPath表达式解决方案的回答,该解决方案精确地选择了所需的节点。:)您没有在此处修改文档,这就是它显示相同内容的原因。例如,您在DOM对象上提供了调用
replaceChild
,您只是创建了一个变量,稍后您将使用
saveXML
好问题+1的输出覆盖该变量。请参阅我对一个XPath表达式解决方案的回答,该解决方案精确地选择了所需的节点。:)我在你写的另一篇文章中看到了这段代码,但是a)我得到了一个错误
致命错误:对非对象调用成员函数insertBefore()
,b)我如何调整它以仅删除具有特定ID的a元素?@Jack:对不起,我的错,函数参数应该是
$from
而不是
$node
。固定的谢谢你指出这一点。还添加了获取具有特定
id
的节点的示例;如何输出修改后的数据?当我使用您为特定ID提供的示例时,我得到了与前面相同的错误。@Jack:use for output。对于错误,您是否更新了代码?这对我来说没问题,你是对的。新的准则是措辞。我要求的是一些不存在的东西。经过一点调整,它完成了所需的工作。非常感谢你!我在你写的另一篇文章中看到了这段代码,但是a)我得到了一个错误
致命错误:对非对象调用成员函数insertBefore()
,b)我如何调整它以仅删除具有特定ID的a元素?@Jack:对不起,我的错,函数参数应该是
$from
而不是
$node
。固定的谢谢你指出这一点。还添加了获取具有特定
id
的节点的示例;如何输出修改后的数据?当我使用您为特定ID提供的示例时,我得到了与前面相同的错误。@Jack:use for output。对于错误,您是否更新了代码?这对我来说没问题,你是对的。新的准则是措辞。我要求的是一些不存在的东西。经过一点调整,它完成了所需的工作。非常感谢你!Can
$child=$link->removeChild($link->firstChild)只需写为
$child=$link->firstChild?可以
$child=$link->removeChild($link->firstChild)只需写为
$child=$link->firstChild