Ошибки/предупреждения 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 в/home/wbkrnl/public_html/new-mvc/1.php в строке 17

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

Author: Klaas Sangers, 2011-05-23

6 answers

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

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

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML('...');
libxml_clear_errors();
 152
Author: lonesomeday, 2017-07-25 07:35:13

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

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

 6
Author: halfer, 2015-12-02 10:47:11

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

@$dom->loadHTML($htmlString);
 6
Author: Ilker Mutlu, 2017-12-11 09:23:09

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

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

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

Удачи.

 1
Author: Emiliano Sangoi, 2016-07-07 00:40:28

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

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

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

 0
Author: user2782001, 2017-01-25 19:12:07

Теги HTML5 почти всегда используют такие атрибуты, как идентификатор, класс и так далее. Таким образом, код для замены будет следующим:

$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);
 -4
Author: Sergey Kaluzhsky, 2016-10-18 09:06:12