2009-12-19 14 views
16

Estoy tratando de analizar algo de HTML con DOM en PHP, pero estoy teniendo algunos problemas. Primero, en caso de que esto cambie la solución, el HTML que tengo no es una página completa, sino que es solo una parte.¿Cómo se analiza el HTML parcial?

<!-- This is the HTML that I have --><a href='/games/'> 
<div id='game'> 
<img src='http://images.example.com/games.gif' width='300' height='137' border='0'> 
<br><b> Game </b> 
</div> 
<div id='double'> 
<img src='http://images.example.com/double.gif' width='300' height='27' border='0' alt='' title=''> 
</div> 
</a> 

Ahora estoy tratando de obtener sólo el div con el id double. He intentado con el siguiente código, pero parece que no funciona correctamente. ¿Qué podría estar haciendo mal?

//The HTML has been loaded into the variable $html 
$dom=new domDocument; 
$dom->loadHTML($html); 
$dom->preserveWhiteSpace = false; 
$keepme = $dom->getElementById('double'); 

$contents = '<div style="text-align:center">'.$keepme.'</a></div>'; 
echo $contents; 
+0

Lo que está haciendo o no haciendo? –

Respuesta

13

Creo DOMDocument::getElementById no funcionará en su caso: (citando)

Para esta función para trabajar, lo necesidad ya sea para establecer los atributos de un documento de identidad con DOMElement::setIdAttribute o una DTD que define un atributo para ser del tipo ID.
En el caso posterior, deberá validar su documento con DOMDocument::validate o DOMDocument->validateOnParse antes de usando esta función.


Una solución que podría funcionar está utilizando algún XPath query para extraer el elemento que busca.

En primer lugar, vamos a cargar la parte de HTML, como si primero lo hizo:

$dom=new domDocument; 
$dom->loadHTML($html); 
var_dump($dom->saveHTML()); 

El var_dump está aquí sólo para probar que la parte HTML ha sido cargado con éxito - a juzgar por su salida, que tiene .


Entonces, instanciar la clase DOMXPath, y lo utilizan para consultar el elemento que desee obtener:

$xpath = new DOMXpath($dom); 
$result = $xpath->query("//*[@id = 'double']"); 
$keepme = $result->item(0); 

Ahora tenemos que elemento que desea ;-)


Pero , para inyectar su contenido HTML en otro segmento HTML, primero debemos obtener su contenido HTML.

no recuerdo ninguna manera "fácil" de hacer eso, pero algo como esto SOULD hacer el truco:

$tempDom = new DOMDocument(); 
$tempImported = $tempDom->importNode($keepme, true); 
$tempDom->appendChild($tempImported); 
$newHtml = $tempDom->saveHTML(); 
var_dump($newHtml); 

Y ... Tenemos el contenido HTML de su double<div>:

string '<div id="double"> 
<img src="http://images.example.com/double.gif" width="300" height="27" border="0" alt="" title=""> 
</div> 
' (length=125) 


Ahora, sólo hay que hacer lo que quiera con él ;-)

0

HTML Tidy debe ser capaz de "corregir" los documentos HTML rotas y fragmentadas, convirtiéndolos en algo que puede ser analizada con otras herramientas

http://devzone.zend.com/article/761

La extensión Tidy es nuevo en PHP 5, y está disponible desde la versión PHP 5.0b3 hacia arriba. Se basa en la biblioteca TidyLib y permite al desarrollador validar, reparar y analizar documentos HTML, XHTML y XML desde PHP.

3

De DomDocument::getElementById

Para que esta función trabaje, se quiere necesidad ya sea para establecer los atributos de un documento de identidad con DOMElement :: setIdAttribute o una DTD que define un atributo de ser de tipo ID . En el caso posterior, usted necesitará validar su documento con DOMDocument :: validate o DOMDocument-> validateOnParse antes de usando esta función.

Para información adicional

Y puesto que alguien va a hablar de hacerlo con una expresión regular más pronto o más tarde, aquí es el patrón se puede utilizar: /<div id='double'>(.*)<\/div>/simU

En addi Por ejemplo, puede usar funciones de cadena regulares para extraer la parte div, p.

$div = strstr($html, '<div id="double">'); 
$div = substr($div, 0, strpos($div, '</div>') + 6); 
echo $div; 

Aunque estoy de acuerdo, no se debe utilizar funciones RegEx o cadena de análisis HTML o XML, lo encuentro absolutamente bien para hacerlo, el tiempo que su única preocupación es conseguir que esta única div de los fragmentos Mantenlo simple.

+1

A menos que existan etiquetas div anidadas, por supuesto.Las expresiones regulares son * no * para analizar html. – troelskn

+0

Estoy de acuerdo si realmente * analizara * ese fragmento. pero solo quiere extraer una pieza claramente definida de ella. No es como si estuviera atravesando el DOM, así que supongo que está bien tratar el fragmento como una cadena. – Gordon

+0

Además, ya lo señalé a SimpleHTML en la primera oración. – Gordon

0

Un documento XML solo puede tener un elemento en el nivel raíz. Probablemente, el analizador HTML tiene un requisito similar. Intente envolver el contenido en una etiqueta <body/>.

Parece que es otra cosa. This page describe cuál puede ser la causa. Te recomendaría que uses XPath para obtener el elemento.

-1

El fragmento es HTML, pero para ser analizado a través de DOM debe XHTML. Todas las etiquetas abiertas deben estar cerradas.

En su caso esto significa que usted debe reemplazar <br> con <br /> y <img ... > con <img ... />

+0

Eso no es verdad. $ dom-> loadHTML ("


") funciona bien y no falla en el análisis. De hecho, $ dom-> saveXML() mostrará su salida con etiquetas cerradas correctamente. –

+0

Todo depende de la biblioteca que use. En python: xml.dom.minidom.parseString ("
") -> devuelve una excepción. xml.dom.minidom.parseString ("
") funciona. Prefiero tener la entrada en el formato correcto en primer lugar que depender de una biblioteca para analizar la entrada incorrecta como espero. – filippo

Cuestiones relacionadas