在PHP中使用DOMDocument替换html

时间:2012-08-27 05:42:18

标签: php xml

我正在尝试使用DOMDocument清理一些糟糕的HTML。 html有一个<div class="article">元素,而<br/><br/>代替</p><p> - 我想将这些元素复制到段落中......但似乎无法将我的节点恢复为原始文档:

//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 个答案:

答案 0 :(得分:2)

有几个问题:

  1. $xpath->query返回nodeList,而不是节点。您必须从nodeList
  2. 中选择一个项目
  3. replaceChild()期望第一个参数是新节点,第二个是要替换的节点
  4. $ article_new是另一个文档的一部分,您首先必须将该节点导入$ doc
  5. 固定代码:

    //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);
    

    您可以创建$ article_htm2的DocumentFragment而不是使用2个文档,并将此片段用作替换。

答案 1 :(得分:1)

我认为应该是

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

这篇文章本身并不是孩子。