2012-03-06 13 views
11

Chcę wyodrębnić treść treści strony html wraz z tagname ich potomka. Podjąłem przykład html w ten sposób:php DOMDocument nodeName Właściwość zwracająca '#text' z nodeName

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

Zaimplementowałem kod php jak poniżej i działa poprawnie.

$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.">"; 
} 

Ten kod działa perfekcyjnie, ale gdy próbowałem zrobić to za pomocą pętli foreach zamiast pętli, właściwość nodeName wracał „#text” z każdej rzeczywistej nodeName. Oto kod

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

Dlaczego tak jest?

Odpowiedz

13

W DOM wszystko jest "węzłem". Nie tylko elementy (tagi); komentarze i tekst między elementami (nawet jeśli są to tylko spacje lub znaki nowej linii, co wydaje się mieć miejsce w twoim przykładzie) również są węzłami. Ponieważ węzły tekstowe nie mają rzeczywistej nazwy węzła, jest ona zastępowana przez #text, aby wskazać, że jest to specjalny rodzaj węzła.

Najwyraźniej węzły tekstowe są pomijane podczas ręcznego wybierania węzłów potomnych za pomocą metody item, ale są uwzględniane podczas iterowania po wartości DOMNodeList. Nie jestem pewien, dlaczego klasa zachowuje się tak, ktoś inny będzie musiał odpowiedzieć na to pytanie.

Oprócz nodeName i nodeValue, a DOMNode ma również właściwość nodeType. Sprawdzając tę ​​właściwość przed certain constants można określić typ węzła, a tym samym odfiltrować niechciane węzły.

+0

Odkryto, że możesz rozwiązać kłótnię nextSibling rodziny DOM z nextElementSibling! Damn you ↵'s i Leo

4

Trochę się spóźniłem, ale najlepsze rozwiązanie dla mnie było inne. Problem polega na tym, że węzeł TEXT nie zna jego nazwy, ale jego rodzic robi wszystko, co trzeba wiedzieć, to poprosić jego rodzica o wartość nodeValue, aby uzyskać klucz.

$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

Po napotkaniu tego problemu naprawiono go, wykonując następujące czynności.

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

Możesz wyśledzić swój $ node-> nodeType, aby zobaczyć różnicę. Otrzymuję 3, 1, 3, mimo że był tylko jeden węzeł (dziecko). Wyłącz białą przestrzeń i teraz otrzymuję 1.

GL.

+1

Dziękujemy! Bardzo mi pomogło. –

Powiązane problemy