2012-08-27 38 views
0

我想清理一些使用DOMDocument的错误html。在HTML有一个<div class="article">元素,与<br/><br/>代替</p><p> - 我想正则表达式这些几段......但似乎无法让我的节点退回到原始文档:在PHP中使用DOMDocument替换html

//load entire doc 
$doc = new DOMDocument(); 
$doc->loadHTML($htm); 
$xpath = new DOMXpath($doc); 
//get the article 
$article = $xpath->query("//div[@class='article']")->parentNode; 
//get as string 
$article_htm = $doc->saveXML($article); 
//regex the bad markup 
$article_htm2 = preg_replace('/<br\/><br\/>/i', '</p><p>', $article_htm); 

//create new doc w/ new html string 
$doc2 = new DOMDocument(); 
$doc2->loadHTML($article_htm2); 
$xpath2 = new DOMXpath($doc2); 

//get the original article node 
$article_old = $xpath->query("//div[@class='article']"); 
//get the new article node 
$article_new = $xpath2->query("//div[@class='article']"); 

//replace original node with new node 
$article->replaceChild($article_old, $article_new); 
$article_htm_new = $doc->saveXML(); 

//dump string 
var_dump($article_htm_new); 

我得到的是500内部服务器错误...不知道我做错了什么。

回答

2

有几个问题:

  1. $xpath->query返回一个节点列表,而不是一个节点。你必须从节点列表
  2. 的replaceChild选择一项()预计,作为第一个参数的新节点,作为第二要替换的节点
  3. $ article_new是另一个文档的一部分,首先必须导入节点为$ DOC

固定码:

//load entire doc 
$doc = new DOMDocument(); 
$doc->loadHTML($htm); 
$xpath = new DOMXpath($doc); 
//get the article 
$article = $xpath->query("//div[@class='article']")->item(0)->parentNode; 
//get as string 
$article_htm = $doc->saveXML($article); 
//regex the bad markup 
$article_htm2 = preg_replace('/<br\/><br\/>/i', '</p>xxx<p>', $article_htm); 

//create new doc w/ new html string 
$doc2 = new DOMDocument(); 
$doc2->loadHTML($article_htm2); 
$xpath2 = new DOMXpath($doc2); 

//get the original article node 
$article_old = $xpath->query("//div[@class='article']")->item(0); 
//get the new article node 
$article_new = $xpath2->query("//div[@class='article']")->item(0); 

//import the new node into $doc 
$article_new=$doc->importNode($article_new,true); 

//replace original node with new node 
$article->replaceChild($article_new, $article_old); 
$article_htm_new = $doc->saveHTML(); 

//dump string 
var_dump($article_htm_new); 

而不是使用2个文件可以创建的$ article_htm2一个DocumentFragment的,并使用该片段作为替代。

1

我觉得应该是

$article->parentNode->replaceChild($article_old, $article_new); 

文章本身不是一个孩子。