PHP DOMDocument ошибки / предупреждения на html5-теги

Я пытался разобрать HTML5-код, чтобы установить атрибуты / значения в коде, но, похоже, DOMDocument(PHP5.3) не поддерживает теги, такие как <nav> и <section>.

есть ли способ проанализировать это как HTML в PHP и манипулировать кодом?


код для воспроизведения:

<?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 (): тег nav недопустимый в сущности, строка: 4 в / главная/wbkrnl/public_html/new-mvc / 1.РНР в строке 17

предупреждение: DOMDocument:: loadHTML (): тег раздел недопустимый в сущности, строка: 10 в / главная/wbkrnl/public_html/new-mvc / 1.РНР в строке 17

6 ответов


нет, нет способа указать конкретный doctype для использования или изменить требования существующего.

лучшим работоспособным решением будет отключение отчетов об ошибках с помощью libxml_use_internal_errors:

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

вы можете фильтровать ошибки, которые вы получаете от парсера. В соответствии с другими ответами здесь отключите отчеты об ошибках на экране, а затем повторите ошибки и покажите только те, которые вы хотите:

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, эти можно фильтровать вне довольно легко.


вы также можете сделать

@$dom->loadHTML($htmlString);

это сработало для меня:

$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 и используйте идентификатор. Например:

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

это не лучшее решение, но в зависимости от ситуации это может быть полезно.

удачи.


Кажется, что нет способа убить предупреждения, но не ошибки. PHP имеет константы, которые должны это делать, но они, похоже, не работают. Вот что должно работать, но не потому, что (ошибка?)....

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

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


теги 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);