2011-05-22 11 views
84

Próbowałem parsować kod HTML5, dzięki czemu mogę ustawić atrybuty/wartości w kodzie, ale wygląda na to, że DOMDocument (PHP5.3) nie obsługuje tagów takich jak <nav> i <section>.PHP DOMDocument błędy/ostrzeżenia na html5-tags

Czy istnieje sposób na parsowanie tego jako HTML w PHP i manipulowanie kodu?


Kod odtworzenia:

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

Błąd

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 dla mnie 'loadHTML ($ HTML5)' zwraca false (niepowodzenie)! Muszę zmienić nowe tagi na DIV ... To nie jest tylko problem "ostrzeżeń" na moim ekranie. –

+1

Ten problem został zgłoszony dla PHP na stronie https://bugs.php.net/bug.php? id = 60021, który z kolei wywołał żądanie funkcji w bazowym pliku libxml2: https://bugzilla.gnome.org/show_bug.cgi?id=761534 – cweiske

Odpowiedz

136

Nie, nie ma możliwości określenia konkretnego typu dokumentu do używania lub modyfikowania jej wymagania istniejący.

Najlepszym rozwiązaniem wykonalne będzie wyłączyć raportowanie błędów z libxml_use_internal_errors:

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

Ops, dla mnie 'loadHTML ($ HTML5)' zwraca FALSE (niepowodzenie)! Muszę zmienić nowe tagi na DIV ... –

+0

Awesome, bardzo dziękuję za odpowiedź i @Klaas dziękuję za pytanie. – whitesiroi

+5

Dowolny powód wbudowanego parsera DOM __ * php7 * __ nie może obsłużyć HTML5? Od tej odpowiedzi minęło 6 lat. –

7

Można również zrobić

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

Eliminacja błędów nie jest właściwą metodą rozwiązania tego problemu. –

+4

@KlaasSangers Dopóki nie mamy nieuszkodzonej implementacji DOM, obawiam się, że jest (albo poprzez '@' lub 'libxml_ *') – Dan

+5

tak, w tym konkretnym przypadku, supresja błędów jest najlepszym rozwiązaniem, moim zdaniem. chyba że wiesz, że HTML, który będziesz ładował, ma być w 100% prawidłowym kodem HTML według definicji PHP. co z mojego doświadczenia nigdy nie ma miejsca. – hanshenrik

5

można filtrować błędy można uzyskać z parsera. Zgodnie z innymi odpowiedziami tutaj wyłączyć raportowanie błędów na ekranie, a następnie iterację błędy i pokazać tylko te, które chcesz:

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

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

Oto print_r() pojedynczego błędu:

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

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

Dzięki dopasowaniu do message i/lub code można je dość łatwo odfiltrować.

1

Ten pracował dla mnie:

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

Jeśli potrzebujesz tag nagłówka, zmień nagłówek ze znacznikiem div i użyć identyfikatora. Na przykład:

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

To nie jest najlepsze rozwiązanie, ale w zależności od sytuacji może być użyteczne.

Powodzenia.

-3

Znaczniki HTML5 prawie zawsze używają atrybutów takich jak id, klasa i tak dalej. Tak więc kod do zastąpienia będzie:

$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

Nie wydaje się być sposobem na zabijanie ostrzeżeń, ale nie błędów. PHP ma stałe, które mają to robić, ale nie wydają się działać. Oto, co to powinno działać, ale nie dlatego, że (bug?) ....

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

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

+0

To jest naprawiony błąd: https://bugs.php.net/bug.php?id=74004 –

+0

Zgodnie z tym wpisem https://stackoverflow.com/a/41845049/937477 ten błąd został naprawiony –

Powiązane problemy