Ошибки/предупреждения 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 недействителен в Entity, строка: 4 в /home/wbkrnl/public _html/new-mvc/1.php в строке 17

Предупреждение: DOMDocument:: loadHTML(): тег раздел недействителен в Entity, строка: 10 в /home/wbkrnl/public _html/new-mvc/1.php в строке 17

Ответ 1

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

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

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

Ответ 2

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

@$dom->loadHTML($htmlString);

Ответ 3

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

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

Ответ 4

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

$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>");

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

Удачи.

Ответ 5

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

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

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

Ответ 6

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