2011-05-22 1 views
84

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

Есть ли способ проанализировать это как 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>"); 

Ошибка

Warning: DOMDocument::loadHTML(): Tag nav invalid in Entity, line: 4 in /home/wbkrnl/public_html/new-mvc/1.php on line 17

Warning: DOMDocument::loadHTML(): Tag section invalid in Entity, line: 10 in /home/wbkrnl/public_html/new-mvc/1.php on line 17

+0

Ops, для меня 'loadHTML (HTML5 $)' возвращает FALSE (отказ)! Мне нужно изменить новые теги на DIVs ... Это не только проблема «предупреждений» на моем экране. –

+1

Эта проблема была опубликована для PHP по адресу https://bugs.php.net/bug.php? id = 60021, который, в свою очередь, породил запрос функции в базовом libxml2: https://bugzilla.gnome.org/show_bug.cgi?id=761534 – cweiske

ответ

136

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

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

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

Ops, для меня 'loadHTML ($ HTML5)' возвращает FALSE (сбой)! Мне нужно изменить новые теги на DIVs ... –

+0

Удивительно, большое спасибо за ответ, и @ Клаас благодарит вас за вопрос. – whitesiroi

+5

Любая причина __ * php7 * __ встроенный DOM-парсер _still_ не может обрабатывать HTML5? Прошло 6 лет с момента подачи этого ответа. –

7

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

@$dom->loadHTML($htmlString); 
+11

Подавление ошибок - это не правильный способ решения этой проблемы. –

+4

@KlaasSangers До тех пор, пока у нас не будет калечащая реализация DOM, я боюсь, что это (либо через '@', либо 'libxml_ *') – Dan

+5

Да, в этом конкретном случае подавление ошибок - лучшее решение, на мой взгляд. если вы не знаете, что HTML, который вы загружаете, должен быть 100% действительным HTML для определения PHP. который по моему опыту никогда не бывает. – hanshenrik

5

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

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

1

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

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

Если вам нужен тег заголовка, изменить заголовок с сНом тегом и использовать идентификатор. Например:

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

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

Удачи.

-3

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

Невозможно убить предупреждения, но не ошибки. 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

Это исправленная ошибка: https://bugs.php.net/bug.php?id=74004 –

+0

В соответствии с этим сообщением https://stackoverflow.com/a/41845049/937477 эта ошибка исправлена –