php - tag - Loop sobre DOMDocument
the_tags wordpress (4)
Sigo la sugerencia de esta pregunta Robust, Mature HTML Parser for PHP , sobre el análisis de html que puede tener un formato incorrecto con DOMDocument .
¿Hay alguna manera fácil de recorrer el documento analizado? Así que me gustaría hacer un bucle en html como este.
$html=''<ul>
<li>value1</li>
<li>value1</li>
<li>value3
<p>subvalue</p>
</li>
</ul>
<p>hello world</p>'';
$doc = new DOMDocument();
$doc->loadHTML($html);
???
foreach (??? as $node)
{
print $node->nodeName.'':''.$node->nodeValue;
}
Y obtener resultados algo como esto.
ul:
li:value1
li:value2
li:value3
p:subvalue
p:hello world
Usar $doc->childNodes
por sí mismo no hace realmente lo que quiero. Ya que no parece bajar a ramas más bajas en el árbol. Utilicé el código sugerido por halfdan y obtengo resultados como este.
html:
html:value1
value1
value3
subvalue
hello world
Debe usar PHP Simple HTML DOM Parser y el siguiente código:
<?php
require_once ''simplehtmldom/simple_html_dom.php'';
function iterateHtmlElements($html)
{
$dom = str_get_html($html);
$dom->set_callback(''handleElement'');
$dom->__toString();
echo "/n";
}
function handleElement(simple_html_dom_node $elem)
{
if($elem->tag == ''text'') {
echo $elem->innertext();
}
else {
echo "/n" . $elem->tag . ": ";
}
}
$html=''<ul>
<li>value1</li>
<li>value1</li>
<li>value3
<p>subvalue</p>
</li>
</ul>
<p>hello world</p>'';
iterateHtmlElements($html);
Funciona exactamente como se esperaba. Lo comprobé con la entrada que proporcionó y obtuve los siguientes resultados:
> php test2.php
ul:
li: value1
li: value1
li: value3
p: subvalue
p: hello world
Estaba teniendo problemas con los elementos que tenían datos de C, donde incluso los elementos que no tenían hijos eran más retrospectivos.
No estoy seguro de por qué fue.
El trabajo alrededor que encontré fue cambiar
if($node->hasChildNodes()) {
showDOMNode($node);
}
a
if($node->childNodes->length != 1) {
showDOMNode($node);
}
Y el código ahora funciona perfectamente.
Prueba esto:
$doc = new DOMDocument();
$doc->loadHTML($html);
showDOMNode($doc);
function showDOMNode(DOMNode $domNode) {
foreach ($domNode->childNodes as $node)
{
print $node->nodeName.'':''.$node->nodeValue;
if($node->hasChildNodes()) {
showDOMNode($node);
}
}
}
Una forma es caminar por el árbol de la siguiente manera:
function next_node($node)
{
if($node->firstChild != null)
{
return $node->firstChild;
}
if($node->nextSibling != null)
{
return $node->nextSibling;
}
for($node = $node->parentNode; $node != null; $node = $node->parentNode)
{
if($node->nextSibling != null)
{
return $node->nextSibling;
}
}
return null;
}
for($node = $doc; $node != null; $node = next_node($node))
{
// handle node (read-only mode, if you need read-write
// you have to save all the nodes in an array and then
// use that array
//
...
}
Esto funciona para la mayoría de los documentos, sin embargo, parece que a veces el parentNode
no está configurado correctamente y la función next_node()
termina devolviendo la información incorrecta.