0

我正在尝试使用 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 内部服务器错误......不知道我做错了什么。

4

2 回答 2

2

有几个问题:

  1. $xpath->query返回一个 nodeList,而不是一个节点。您必须从 nodeList 中选择一个项目
  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);

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

于 2012-08-27T06:52:37.060 回答
1

我认为应该是

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

这篇文章不是自己的孩子。

于 2012-08-27T05:48:48.340 回答