7

PHPのDOMDocument::loadHTMLを使用してhtmlタグを編集しようとしています。htmlデータはhtmlの一部であり、ページ全体ではありません。このページ(PHP-DOMDocument-既存のHTMLタグを新しいものに変更/置換する必要がある)の内容に従いました。

これにより、preタグがdivタグに変換されますが、「致命的なエラー:キャッチされない例外'DOMException'とメッセージ'NotFoundError'」が表示されます。

<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;

$dom = new DOMDocument;
@$dom->loadHTML($contents);

foreach( $dom->getElementsByTagName("pre") as $nodePre ) {
    $nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
    $dom->replaceChild($nodeDiv, $nodePre);
}

echo $dom->saveHTML();
?>

[編集]ノードオブジェクトを逆方向に反復しようとすると、次のエラーが発生します。「注意:非オブジェクトのプロパティを取得しようとしています...」

<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;

$dom = new DOMDocument;
@$dom->loadHTML($contents);
$domPre = $dom->getElementsByTagName('pre');
$length = $domPre->length;

    For ($i = $length; $i > -1 ; $i--) {
        $nodePre = $domPre->item($i);
        echo $nodePre->nodeValue . '<br />';
//      $nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
//      $dom->replaceChild($nodeDiv, $nodePre);
    }

    // echo $dom->saveHTML();
?>

[編集]オーケー、解決しました。回答されたコードにエラーがあるため、ここに解決策を投稿します。皆さんありがとう。

解決:

<?php
$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;

$dom = new DOMDocument;
@$dom->loadHTML($contents);
$domPre = $dom->getElementsByTagName('pre');
$length = $domPre->length;

For ($i = $length - 1; $i > -1 ; $i--) {
    $nodePre = $domPre->item($i);
    $nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
    $nodePre->parentNode->replaceChild($nodeDiv, $nodePre);
}

echo $dom->saveHTML();
?>
4

2 に答える 2

16

問題はへの呼び出しreplaceChild()です。それよりも

$dom->replaceChild($nodeDiv, $nodePre);

使用する

$nodePre->parentNode->replaceChild($nodeDiv, $nodePre);

アップデート

これが動作するコードです。複数のノードの置き換えに問題があるようです(詳細はこちら:http://php.net/manual/en/domnode.replacechild.php)。そのため、要素を置き換えるには回帰ループを使用する必要があります。

$contents = <<<STR
<pre>hi</pre>
<pre>hello</pre>
<pre>bye</pre>
STR;

$dom = new DOMDocument;
@$dom->loadHTML($contents);

$elements = $dom->getElementsByTagName("pre");
for ($i = $elements->length - 1; $i >= 0; $i --) {
    $nodePre = $elements->item($i);
    $nodeDiv = $dom->createElement("div", $nodePre->nodeValue);
    $nodePre->parentNode->replaceChild($nodeDiv, $nodePre);
}
于 2012-08-18T13:04:20.637 に答える
3

paquettg / php-html-parserを使用した別の方法(名前を変更する方法が見つからなかったため、再バインドでハックを使用する必要がありました$this):

use PHPHtmlParser\Dom;
use PHPHtmlParser\Dom\HtmlNode;

$dom = new Dom;
$dom->load($text);
/** @var HtmlNode[] $tags */
foreach($dom->find('pre') as $tag) {
    $changeTag = function() {
        $this->name = 'div';
    };
    $changeTag->call($tag->tag);
};
echo (string)$dom;
于 2017-08-30T16:49:01.320 に答える