HTML5タグのPHP DOMDocumentエラー/警告


105

コード内で属性/値を設定できるようにHTML5コードを解析しようとしましたが、DOMDocument(PHP5.3)は<nav>およびのようなタグをサポートしていないよう<section>です。

これをPHPでHTMLとして解析し、コードを操作する方法はありますか?


再現するコード:

<?php
$dom = new DOMDocument();
$dom->loadHTML("<!DOCTYPE HTML>
<html><head><title>test</title></head>
<body>
<nav>
  <ul>
    <li>first
    <li>second
  </ul>
</nav>
<section>
  ...
</section>
</body>
</html>");

エラー

警告:DOMDocument :: loadHTML():タグナビゲーションはエンティティでは無効です。行:4 /home/wbkrnl/public_html/new-mvc/1.phpの行17

警告:DOMDocument :: loadHTML():タグセクションがエンティティで無効です。行:10 /home/wbkrnl/public_html/new-mvc/1.phpの行17


Ops、私にとってloadHTML($HTML5)はFALSE(失敗)を返します!新しいタグをDIVに変更する必要があります...画面の「警告」の問題だけではありません。
Peter Krauss

2
この問題は、bugs.php.net / bug.php?id = 60021の PHPで報告されていました。これにより、基になるlibxml2に機能リクエストが生成されました:bugzilla.gnome.org/show_bug.cgi
id

回答:


193

いいえ、使用する特定のdoctypeを指定したり、既存のdoctypeの要件を変更したりする方法はありません。

あなたの最良の実行可能な解決策は、エラー報告を無効にすることlibxml_use_internal_errorsです:

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML('...');
libxml_clear_errors();

1
Ops、私にとってloadHTML($HTML5)はFALSE(失敗)を返します!新しいタグをDIVに変更する必要があります...
Peter Krauss

21
php7の組み込みDOMパーサーがまだ HTML5を処理できない理由はですか?この回答が提出されてから6年になります。
スーパーキャット

1
@SuperCatこれはすべて、基盤となるlibxmlライブラリに依存しています。
lonesomeday

6
--- HTML5を言及しないように、XMLではありませんでした決して、...となっている、もなります
Kevin_Kinsey

2
2019年の更新:警告は引き続き発生しますがloadHTML、実際にはHTML5タグを受け入れます。

9

あなたもすることができます

@$dom->loadHTML($htmlString);

16
エラーの抑制は、この問題に対処する適切な方法ではありません。
Klaas Sangers 2014

6
@KlaasSangers我々は非不自由DOM実装を持ってまで、私はそれが(いずれかを介してである怖い@libxml_*
ダンLugg

6
ええ、この特定のケースでは、エラーの抑制が最善の解決策だと私は考えています。ロードするHTMLがわかっていない限り、PHPの定義ごとに100%有効なHTMLであると見なされます。私の経験では、そうではありません。
hanshenrik 2015

@KlaasSangers ...どうして?
Nick Manning

PHP8「@演算子で致命的なエラーが抑制されないこの変更により、PHP 8より前に非表示になっていたエラーが明らかになる可能性があります。本番サーバーでdisplay_errors = Offを設定してください! stitcher.io/blog/new-in-php-8
マーカス

7

パーサーから取得したエラーをフィルタリングできます。ここでの他の回答と同様に、画面へのエラー報告をオフにしてから、エラーを繰り返し処理し、必要なエラーのみを表示します。

libxml_use_internal_errors(TRUE);
// Do your load here
$errors = libxml_get_errors();

foreach ($errors as $error)
{
    /* @var $error LibXMLError */
}

これがprint_r()単一のエラーの例です。

LibXMLError Object
(
    [level] => 2
    [code] => 801
    [column] => 17
    [message] => Tag section invalid

    [file] => 
    [line] => 39
)

messageおよび/またはで照合することによりcode、これらを簡単に除外できます。


2

警告を消す方法はないようですが、エラーを消す方法はありません。PHPには、これを行うことが想定されている定数がありますが、動作しないようです。これはSHOULDの動作ですが、そうではありません(バグ?)....

 $doc=new DOMDocument();
 $doc->loadHTML("<tagthatdoesnotexist><h1>Hi</h1></tagthatdoesnotexist>", LIBXML_NOWARNING );
 echo $doc->saveHTML();

http://php.net/manual/en/libxml.constants.php


このポストstackoverflow.com/a/41845049/937477によると、このバグは修正されています
mmmmm

1
単純に言えば、それは有効なHTML5ではありません。カスタム要素には、仕様に従ってハイフンを含める
Greg

@グレッグ知っておくと良い。これは、XMLパーサーがタグが無効であることを認識し、フラグのために無視することを示すための単なるテストです。
-user2782001

0

これは私のために働きました:

$html = file_get_contents($url);

$search = array("<header>", "</header>", "<nav>", "</nav>", "<section>", "</section>");
$replace = array("<div>", "</div>","<div>", "</div>", "<div>", "</div>");
$html = str_replace($search, $replace, $html);

$dom = new DOMDocument();
$dom->loadHTML($html);

ヘッダータグが必要な場合は、ヘッダーをdivタグで変更し、IDを使用します。例えば:

$search = array("<header>", "</header>");
$replace = array("<div id='header1'>", "</div>");

これは最善の解決策ではありませんが、状況によっては役立つ場合があります。

幸運を。


-5

HTML5タグは、ほとんどの場合、id、classなどの属性を使用します。したがって、置き換えるコードは次のようになります。

$html = file_get_contents($url);
$search = array(
    "<header", "</header>", 
    "<nav", "</nav>", 
    "<section", "</section>",
    "<article", "</article>",
    "<footer", "</footer>",
    "<aside", "</aside>",
    "<noindex", "</noindex>",
);
$replace = array(
    "<div", "</div>",
    "<div", "</div>", 
    "<div", "</div>",
    "<div", "</div>",
    "<div", "</div>",
    "<div", "</div>",
    "<div", "</div>",
);
$html = str_replace($search, $replace, $html);
$dom = new DOMDocument();
$dom->loadHTML($html);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.