PHP DOMDocument errori / avvertimenti sui tag html5


105

Ho tentato di analizzare il 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>.

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


Codice da 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

Avviso: DOMDocument :: loadHTML (): tag nav non valido in Entity, riga: 4 in /home/wbkrnl/public_html/new-mvc/1.php alla riga 17

Avviso: DOMDocument :: loadHTML (): sezione tag non valida in Entity, riga: 10 in /home/wbkrnl/public_html/new-mvc/1.php alla riga 17


Ops, per me loadHTML($HTML5)restituisce FALSE (fallimento)! Ho bisogno di cambiare i nuovi tag in DIV ... Non è solo un problema di "avvertimenti" sul mio schermo.
Peter Krauss

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

Risposte:


193

No, non è possibile specificare un particolare doctype da utilizzare o modificare i requisiti di quello esistente.

La tua migliore soluzione praticabile sarà disabilitare 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 (fallimento)! Devo cambiare i nuovi tag in DIV ...
Peter Krauss

21
C'è qualche motivo per cui il parser DOM integrato in php7 non riesce ancora a gestire HTML5? Sono passati 6 anni da quando è stata inviata questa risposta.
Super Cat

1
@SuperCat Dipende tutto dalla libreria libxml sottostante.
lonesomeday

6
--- per non parlare di HTML5 non è XML, non è mai stato, è stato, né sarà ...
Kevin_Kinsey

2
Aggiornamento 2019 : l'avviso è ancora attivato, tuttavia loadHTMLora accetta effettivamente i tag HTML5.

9

Potresti anche farlo

@$dom->loadHTML($htmlString);

16
La soppressione degli errori non è un modo corretto di affrontare questo problema.
Klaas Sangers

6
@KlaasSangers Fino a quando non avremo un'implementazione DOM non paralizzata, temo che sia (attraverso @o libxml_*)
Dan Lugg

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

@KlaasSangers ... perché no?
Nick Manning

PHP8 "L'operatore @ non silenzia più gli errori fatali È possibile che questa modifica possa rivelare errori che erano ancora nascosti prima di PHP 8. Assicurati di impostare display_errors = Off sui tuoi server di produzione!" stitcher.io/blog/new-in-php-8
marcus

7

Puoi filtrare gli errori che ricevi dal parser. Come per altre risposte qui, disattiva la segnalazione degli errori sullo schermo, quindi ripeti gli errori e mostra solo quelli che desideri:

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

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

Ecco print_r()un singolo errore:

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

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

Abbinando su messagee / o su code, questi possono essere filtrati abbastanza facilmente.


2

Non sembra esserci un modo per eliminare gli avvisi ma non gli errori. PHP ha costanti che dovrebbero farlo, ma non sembrano funzionare. Ecco cosa DOVREBBE funzionare, ma 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


Secondo questo post stackoverflow.com/a/41845049/937477 quel bug è stato risolto
mmmmm

1
Giusto per essere pedanti, questo non è HTML5 valido. Gli elementi personalizzati devono avere un trattino in base alle specifiche w3c.github.io/webcomponents/spec/custom/…
Greg

@ Greg Buono a sapersi. È solo un test per dimostrare che il parser xml riconoscerà che il tag non è valido, ma lo ignorerà a causa del flag.
user2782001

0

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 hai bisogno del tag di intestazione, modifica l'intestazione con un tag div e utilizza 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.

In bocca al lupo.


-5

I tag HTML5 utilizzano quasi sempre attributi come id, class 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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.