2012-03-06 55 views
11

我想提取html頁面正文的內容以及它的子標記名稱。我已經邁出了例如HTML這樣的:php DOMDocument nodeName屬性返回'#text'與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> 

我已經實現像下面和它的做工精細的PHP代碼。

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

此代碼工作完全正常,但是當我試圖做到這一點使用foreach循環,而不是for循環中,nodeName屬性返航「#text」與每一個實際節點名稱。 這裏是代碼

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

爲什麼這麼說?

回答

13

在DOM中,一切都是'節點'。不只是元素(標籤);元素之間的註釋和文本(即使它只是空白或換行符,在您的示例中似乎就是這種情況)也是節點。由於文本節點沒有實際的節點名稱,因此它被#text替代以指示它是一種特殊的節點。

顯然,使用item方法手動選擇子節點時省略了文本節點,但在迭代DOMNodeList時包含了該節點。我不知道爲什麼班級的行爲如此,其他人將不得不回答這個問題。

除了nodeNamenodeValue,一個DOMNode也有一個nodeType財產。通過檢查此屬性與certain constants,您可以確定節點的類型,從而過濾掉不需要的節點。

+0

發現你可以通過nextElementSibling解決下一代DOM家族的爭吵!該死的呃和<! - 評論 - > – Leo 2016-05-11 00:43:01

4

我來得晚了一點,但對我來說最好的解決方案是不同的。問題在於TEXT節點不知道它的名字,但是他的父節點完成了這一切,所有你需要知道的是,要求他的父節點獲得keyValue。

$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

當我遇到這個問題時,通過執行以下操作來修復它。

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

您可以追蹤出您的$ node-> nodeType以查看差異。即使只有一個節點(孩子),我也會得到3,1,3。關閉空白空間,現在我只得到1.

GL。

+1

謝謝!幫了我很多。 – 2014-03-28 13:17:02

相關問題