Advertencia: DOMDocument :: loadHTML (): htmlParseEntityRef: esperando ';' en la entidad,


88
$html = file_get_contents("http://www.somesite.com/");

$dom = new DOMDocument();
$dom->loadHTML($html);

echo $dom;

lanza

Warning: DOMDocument::loadHTML(): htmlParseEntityRef: expecting ';' in Entity,
Catchable fatal error: Object of class DOMDocument could not be converted to string in test.php on line 10

Respuestas:


147

Para evaporar la advertencia, puede usar libxml_use_internal_errors(true)

// create new DOMDocument
$document = new \DOMDocument('1.0', 'UTF-8');

// set error level
$internalErrors = libxml_use_internal_errors(true);

// load HTML
$document->loadHTML($html);

// Restore error level
libxml_use_internal_errors($internalErrors);

92

Apuesto a que si miras la fuente de http://www.somesite.com/, encontrarás caracteres especiales que no se han convertido a HTML. Quizás algo como esto:

<a href="/script.php?foo=bar&hello=world">link</a>

Debiera ser

<a href="/script.php?foo=bar&amp;hello=world">link</a>

3
Solo para ampliar esto, si el carácter & está incluso en el texto y no es un atributo HTML, aún debe escaparse a & amp ;. La razón por la que el analizador genera el error es porque después de ver un & está esperando un; para terminar la entidad HTML.
— Kyle

21
... y para expandir aún más, llamar htmlentities()o similar en la cadena solucionará el problema.
— Ben

56
$dom->@loadHTML($html);

Esto es incorrecto, use esto en su lugar:

@$dom->loadHTML($html);

26
o $ dom-> strictErrorChecking = false;
— Tjorriemorrie

6
Esta es una solución terrible, ya que hará que los errores en esta línea sean una pesadilla de depurar. La solución de @ Dewsworld es mucho mejor.
— Gerry

¿cuál es la @de?
— Francisco Corrales Morales

2
Esta es una solución muy sucia y no arreglará todo.
— Mirko Brunner

1
Aunque su respuesta solucionará el problema, la línea "Esto es incorrecto" es, en sí misma, incorrecta.
— TecBrat

14

Hay 2 errores: el segundo es porque $ dom no es una cadena sino un objeto y, por lo tanto, no se puede "hacer eco". El primer error es una advertencia de loadHTML, causado por una sintaxis no válida del documento html para cargar (probablemente un & (ampersand) usado como separador de parámetros y no enmascarado como entidad con &).

Usted ignora y suprime este mensaje de error (¡no el error, solo el mensaje!) Llamando a la función con el operador de control de errores "@" ( http://www.php.net/manual/en/language.operators.errorcontrol. php )

@$dom->loadHTML($html);

12

La razón de su error fatal es que DOMDocument no tiene un método __toString () y, por lo tanto, no se puede hacer eco.

Probablemente estas buscando

echo $dom->saveHTML();

10

Independientemente del eco (que debería ser reemplazado por print_r o var_dump), si se lanza una excepción, el objeto debe permanecer vacío:

DOMNodeList Object
(
)

Solución

  1. Establecer recoveren verdadero y strictErrorCheckingfalso

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. Use la codificación de entidad de php en el contenido del marcado, que es una fuente de error más común.


1
En la primera solución, escribió dom en lugar de doc.
— Máthé Endre-Botond

esto funcionó para mí, solo agregué $ content = mb_convert_encoding ($ content, 'HTML-ENTITIES', 'UTF-8');
— Jacek Pietal

8

reemplazar lo simple

$dom->loadHTML($html);

con los más robustos ...

libxml_use_internal_errors(true);

if (!$DOM->loadHTML($page))
    {
        $errors="";
        foreach (libxml_get_errors() as $error)  {
            $errors.=$error->message."<br/>";
        }
        libxml_clear_errors();
        print "libxml errors:<br>$errors";
        return;
    }

8
$html = file_get_contents("http://www.somesite.com/");

$dom = new DOMDocument();
$dom->loadHTML(htmlspecialchars($html));

echo $dom;

prueba esto


3

Otra posible solución es

$sContent = htmlspecialchars($sHTML);
$oDom = new DOMDocument();
$oDom->loadHTML($sContent);
echo html_entity_decode($oDom->saveHTML());

Esto no funcionará. De acuerdo con php.net/manual/en/function.htmlspecialchars.php , todos los caracteres especiales html también se escapan. Tomemos, por ejemplo, este fragmento de código HTML <span>Hello World</span>. Ejecutar esto htmlspecialcharsproducirá lo &lt;span&gt;Hello World&lt/span&gt;que ya no es HTML. DOMDocument :: loadHTML ya no lo tratará como HTML sino como una cadena.
— Twisted Whisper

Esto funciona para mí:$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
— Bartłomiej Jakub Kwiatek

3

Sé que esta es una pregunta antigua, pero si alguna vez desea corregir los signos '&' mal formados en su HTML. Puede usar un código similar a este:

$page = file_get_contents('http://www.example.com');
$page = preg_replace('/\s+/', ' ', trim($page));
fixAmps($page, 0);
$dom->loadHTML($page);


function fixAmps(&$html, $offset) {
    $positionAmp = strpos($html, '&', $offset);
    $positionSemiColumn = strpos($html, ';', $positionAmp+1);

    $string = substr($html, $positionAmp, $positionSemiColumn-$positionAmp+1);

    if ($positionAmp !== false) { // If an '&' can be found.
        if ($positionSemiColumn === false) { // If no ';' can be found.
            $html = substr_replace($html, '&amp;', $positionAmp, 1); // Replace straight away.
        } else if (preg_match('/&(#[0-9]+|[A-Z|a-z|0-9]+);/', $string) === 0) { // If a standard escape cannot be found.
            $html = substr_replace($html, '&amp;', $positionAmp, 1); // This mean we need to escape the '&' sign.
            fixAmps($html, $positionAmp+5); // Recursive call from the new position.
        } else {
            fixAmps($html, $positionAmp+1); // Recursive call from the new position.
        }
    }
}

0

Otra posible solución es que tal vez su archivo sea de tipo ASCII, simplemente cambie el tipo de sus archivos.


-1

Incluso después de esto, mi código funciona bien, así que eliminé todos los mensajes de advertencia con esta declaración en la línea 1.

<?php error_reporting(E_ERROR); ?>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.