2012-03-06 21 views
11

Quiero extraer el contenido del cuerpo de una página html junto con los tagNames de su hijo. Me he tomado un html ejemplo como este:php DOMDocument propiedad nodeName que devuelve '#text' con el nombre de nodo

<html> 
<head></head> 
<body> 
<h1>This is H1 tag</h1> 
<h2>This is H2 tag</h2> 
<h3>This is H3 tag</h3> 
</body> 
</html> 

He implementado el código php, como a continuación y su funcionamiento muy bien.

$d=new DOMDocument(); 
$d->loadHTMLFile('file.html'); 
$l=$d->childNodes->item(1)->childNodes->item(1)->childNodes; 
for($i=0;$i<$l->length;$i++) 
{ 
echo "<".$l->item($i)->nodeName.">".$l->item($i)->nodeValue."</".$l->item($i)->nodeName.">"; 
} 

Este código está funcionando perfectamente bien, pero cuando traté de hacerlo mediante bucle foreach en lugar de para el lazo, la propiedad nombreNodo regresaba '#text' con cada nombreNodo real. aquí es que el código

$l=$d->childNodes->item(1)->childNodes->item(1)->childNodes; 
foreach ($l as $li) { 
    echo $li->childNodes->item(0)->nodeName."<br/>"; 
} 

¿Por qué?

Respuesta

13

En DOM, todo es un 'nodo'. No solo los elementos (etiquetas); los comentarios y el texto entre los elementos (incluso si solo son espacios en blanco o líneas nuevas, que parece ser el caso en su ejemplo) también son nodos. Como los nodos de texto no tienen un nombre de nodo real, se sustituye por #text para indicar que es un tipo especial de nodo.

Aparentemente, los nodos de texto se omiten al seleccionar manualmente los nodos secundarios con el método item, pero se incluyen al iterar sobre el DOMNodeList. No estoy seguro de por qué la clase se comporta así, alguien más tendrá que responder eso.

Al lado de nodeName y nodeValue, un DOMNode también tiene una propiedad de nodeType. Al marcar esta propiedad contra certain constants puede determinar el tipo de nodo y así filtrar los nodos no deseados.

+0

Descubierto que puede resolver la familia DOM próxima pelea entre hermanos con nextElementSibling! ¡Maldito seas! Y Leo

4

Llego un poco tarde a esto, pero la mejor solución para mí fue diferente. El problema es que el nodo TEXTO no sabe su nombre, pero su padre lo hace todo lo que necesita saber, es pedirle a su padre que nodeValue obtenga la clave.

$dom = new DOMDocument(); 
$dom->loadXML($stringXML); 
$valorizador = $dom->getElementsByTagName("tagname"); 
foreach ($valorizador->item(0)->childNodes as $item) { 
    $childs = $item->childNodes; 
    $key = $item->nodeName; 
    foreach ($childs as $i) { 
    echo $key." => ".$i->nodeValue. "\n"; 
    } 
} 
14

Cuando he tenido este problema, se solucionó haciendo lo siguiente.

$xmlDoc = new DOMDocument(); 
$xmlDoc->preserveWhiteSpace = false; // important! 

Puede rastrear su $ node-> nodeType para ver la diferencia. Obtengo 3, 1, 3 a pesar de que solo había un nodo (niño). Apague el espacio en blanco y ahora acabo de obtener 1.

GL.

+1

¡Gracias! Me ayudo mucho. –

Cuestiones relacionadas