2010-05-26 9 views
18

Ich folge dem Vorschlag aus dieser Frage Robust, Mature HTML Parser for PHP, über das Analysieren von HTML, das mit DOMDocument falsch formatiert sein kann.Schleife über DOMDocument

Gibt es eine einfache Möglichkeit, das geparste Dokument zu durchlaufen? Also würde ich gerne über HTML wie diese Schleife.

Und Ergebnisse etwa so erhalten.

ul: 
li:value1 
li:value2 
li:value3 
p:subvalue 
p:hello world 

Mit $doc->childNodes selbst nicht wirklich tun, was ich will. Da scheint es nicht zu niedrigeren Ästen im Baum zu gehen. Ich habe den von halfdan vorgeschlagenen Code verwendet und erhalte Ergebnisse wie diese.

html: 
html:value1 
     value1 
     value3 
      subvalue 

     hello world 
+0

DOM-Objekte können (aber nicht immer) eine Eigenschaft namens $ childNodes haben, über die Sie iterieren können. Sie können mit der hasChildNodes() -Methode prüfen, ob diese Eigenschaft vorhanden ist oder nicht. – GordonM

Antwort

25

Try this:

$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); 
     } 
    }  
} 
+0

Danke, ich habe meine Frage aktualisiert, um klarer zu sein. Ich glaube nicht, dass '$ doc-> childNodes' selbst tut was ich will. Grundsätzlich möchte ich jeden Knoten im Baum besuchen, nicht nur alle Knoten auf einer Ebene. – Zoredache

+0

Okay, gib mir eine Sekunde und ich werde meinen Beitrag aktualisieren. – halfdan

1

Ich habe Probleme mit Elementen, die c-Daten hatten, wo auch Elemente, die keine Kinder haben, wo die Rückkehr, dass sie es taten.

Ich bin mir nicht sicher, warum es war.

Die Arbeit herum war ich fand

if($node->hasChildNodes()) { 
     showDOMNode($node); 
    } 

zu

if($node->childNodes->length != 1) { 
     showDOMNode($node); 
    } 

Und der Code nun perfekt funktioniert zu ändern.

2

Sie müssen PHP Simple HTML DOM Parser verwenden und den folgenden Code:

<?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); 

Es funktioniert genau wie erwartet. Ich habe es mit der Eingabe, die Sie zur Verfügung gestellt und bekam folgende Ergebnisse:

> php test2.php 

ul: 
li: value1 
li: value1 
li: value3 
p: subvalue 
p: hello world 
0

Eine Möglichkeit ist, den Baum wie folgt zu gehen:

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 
    // 
    ... 
} 

Dies ist für die meisten Dokumente funktioniert, aber es ist wie zu Zeiten aussieht die parentNode ist irgendwie nicht richtig eingestellt und die next_node() Funktion endet, die falsche Information zurückgebend.