2011-05-22 1 views
84

Ho tentato di analizzare codice HTML5 in modo da poter impostare attributi/valori all'interno del codice, ma sembra che DOMDocument (PHP5.3) non supporti tag come <nav> e <section>.PHP DOMDocument errori/avvertenze su tag html5

C'è un modo per analizzare questo come HTML in PHP e manipolare il codice?


codice per riprodurre:

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

errore

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, per me 'loadHTML ($ HTML5)' restituisce FALSE (esito negativo)! Devo cambiare i nuovi tag in DIV ... Non è solo un problema di "avvertenze" sul mio schermo. –

+1

Questo problema era stato segnalato per PHP su https://bugs.php.net/bug.php? id = 60021 che a sua volta ha generato una richiesta di funzionalità nella libxml2 sottostante: https://bugzilla.gnome.org/show_bug.cgi?id=761534 – cweiske

risposta

136

No, non c'è modo di specificare un particolare doctype da utilizzare o modificare i requisiti del esistente.

Il tuo migliore soluzione praticabile sta per essere quello di disattivare la segnalazione degli errori con libxml_use_internal_errors:

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

Ops, per me 'loadHTML ($ HTML5)' restituisce FALSE (errore)! Devo cambiare i nuovi tag in DIV ... –

+0

Fantastico, grazie mille per la risposta e @Klaas grazie per la domanda. – whitesiroi

+5

Qualsiasi motivo __ * il parser del DOM incorporato in php7 * __ _still_ non può gestire HTML5? Sono passati 6 anni da quando è stata presentata questa risposta. –

7

Si potrebbe anche fare

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

La soppressione degli errori non è un modo corretto per gestire questo problema. –

+4

@KlaasSangers Fino a quando non avremo un'implementazione DOM non ridotta, temo che sia (tramite '@' o 'libxml_ *') – Dan

+5

sì, in questo caso specifico, la supression degli errori è la soluzione migliore, secondo me. a meno che tu non sappia che l'HTML che caricerai, dovrebbe essere un HTML valido al 100% per ogni definizione di PHP. quale nella mia esperienza, non è mai il caso. – hanshenrik

5

È possibile filtrare gli errori che si ottiene dal parser. Come per le altre risposte qui, disattivare la segnalazione degli errori allo schermo, e poi scorrere gli errori e mostrare solo quelli che si desidera:

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

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

Ecco una print_r() di un singolo errore:

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

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

Corrispondendo allo message e/o allo code, questi possono essere filtrati abbastanza facilmente.

1

questo ha funzionato per me:

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

Se è necessario il tag di intestazione, modificare l'intestazione con un tag div e utilizzare un ID. Per esempio:

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

Non è la soluzione migliore, ma a seconda della situazione può essere utile.

Buona fortuna.

-3

I tag HTML5 utilizzano quasi sempre attributi come id, classe e così via. Quindi il codice per la sostituzione sarà:

$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

Non sembra essere un modo per uccidere avvertenze ma non errori. PHP ha delle costanti che dovrebbero farlo, ma non sembrano funzionare. Ecco ciò che è dovrebbe funzionare, ma lo fa non perché (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

Questo è un bug fisso: https://bugs.php.net/bug.php?id=74004 –

+0

In base a questo post https://stackoverflow.com/a/41845049/937477 il bug è stato corretto –