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
gweg
fuente

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);
Dewsworld
fuente
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>
mattalxndr
fuente
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);
Maanas Royy
fuente
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);
usuario279583
fuente
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();
Mike B
fuente
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.

Lorenz Lo Sauer
fuente
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;
    }
David Chan
fuente
8
$html = file_get_contents("http://www.somesite.com/");

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

echo $dom;

prueba esto

nmwi22
fuente
3

Otra posible solución es

$sContent = htmlspecialchars($sHTML);
$oDom = new DOMDocument();
$oDom->loadHTML($sContent);
echo html_entity_decode($oDom->saveHTML());
lastYorsh
fuente
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.
        }
    }
}
Nicolas Bouvrette
fuente
0

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

FRANCO
fuente
-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); ?>
Satyam Gupta
fuente