2012-08-27 77 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); 

文章本身不是一個孩子。