2010-08-02 18 views
7

Un poco nuevo para el análisis de PHP aquí, pero parece que no puedo obtener que DomDocument de PHP devuelva lo que es claramente un nodo identificable. El HTML cargada vendrá de la 'red por lo que no necesariamente puede garantizar el cumplimiento de XML, pero yo intente lo siguiente:PHP HTML DomDocument getElementById problems

<?php 
header("Content-Type: text/plain"); 

$html = '<html><body>Hello <b id="bid">World</b>.</body></html>'; 

$dom = new DomDocument; 
$dom->preserveWhiteSpace = false; 
$dom->validateOnParse = true; 

/*** load the html into the object ***/ 
$dom->loadHTML($html); 
var_dump($dom);  

$belement = $dom->getElementById("bid"); 
var_dump($belement); 

?> 

Aunque recibo ningún error, sólo recibirá el siguiente como salida:

object(DOMDocument)#1 (0) { 
} 
NULL 

¿No debería ser capaz de buscar la etiqueta <b> ya que de hecho tiene una identificación?

Respuesta

17

The Manual explica por qué:

Para que esto funcione, necesitará ya sea para establecer los atributos de un documento de identidad con DomElement-> setIdAttribute() o una DTD que define un atributo como de tipo ID. En el caso posterior, deberá validar su documento con DOMDocument-> validate() o DOMDocument-> validateOnParse antes de usar esta función.

De todos modos, vaya por válido HTML & proporcionar una DTD.

Soluciones rápidas:

  1. $dom->validate(); de llamada y poner al día con los errores (o solucionarlos), después se puede utilizar $dom->getElementById(), independientemente de los errores por alguna razón.
  2. Uso XPath si no se siente como validing: $x = new DOMXPath($dom); $el = $x->query("//*[@id='bid']")->item(0);
  3. Ahora que lo pienso de ella: si sólo configura validateOnParse a cierto antes cargar el HTML, si también funcionaría; P

.

$dom = new DOMDocument(); 
$html ='<html> 
<body>Hello <b id="bid">World</b>.</body> 
</html>'; 
$dom->validateOnParse = true; //<!-- this first 
$dom->loadHTML($html);  //'cause 'load' == 'parse 

$dom->preserveWhiteSpace = false; 

$belement = $dom->getElementById("bid"); 
echo $belement->nodeValue; 

Salidas 'Mundo' aquí.

+0

Tengo validateOnParse. setIdAttribute solo se aplicaría a establecer y luego recuperar? Sin embargo, una vez más, el HTML será proporcionado por la web, por lo que estoy a su merced, pero solo estoy probando un ejemplo. HTML5 ni siquiera tiene una DTD, ¿sí? – Xailor

+0

"setIdAttribute solo se aplicaría para establecer y luego recuperar?" -> Sí. HTML5 todavía no está terminado, por lo que no debería tener una DTD todavía. –

+0

DTD sería '', pero solo llamar a '$ dom-> validate()' también funcionaría.Preséntese a los errores o intente generar HTML válido (este último es más difícil de lo que parece ... :)) – Wrikken

3

Bueno, usted debe comprobar si $dom->loadHTML($html); devuelve true (éxito) y me gustaría probar

var_dump($belement->nodeValue); 

para la salida para obtener una idea de lo que podría estar mal.

EDIT: http://www.php-editors.com/php_manual/function.domdocument-get-element-by-id.html - parece que DomDocument utiliza XPath internamente.

Ejemplo:

$xpath = xpath_new_context($dom); 
var_dump(xpath_eval_expression($xpath, "//*[@ID = 'YOURIDGOESHERE']")); 
+0

Publicación original modificada para reflejar estas salidas. Gracias, – Xailor