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() は、1 番目の引数として新しいノードを想定し、2 番目の引数として置き換えるノードを想定しています。
  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 を作成し、このフラグメントを置換として使用できます。

于 2012-08-27T06:52:37.060 に答える
1

そうあるべきだと思う

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

記事はそれ自体の子ではありません。

于 2012-08-27T05:48:48.340 に答える