2011-10-24 72 views
2

我要尋找此功能:PHP的DOMDocument/XPath的:獲取HTML文本和環繞標籤

鑑於這是HTML頁:

<body> 
<h1>Hello, 
    <b>world!</b> 
</h1> 
</body> 

我想只包含一個數組DISTINCT文本元素 (無重複)和包圍文本元素標籤的數組:

結果上述「HTML」將是一個陣列,其看起來像這樣:

array => 
"Hello," surrounded by => "h1" and "body" 
"world!" surrounded by => "b", "h1" and "body" 

我alreday做到這一點:

$res=$xpath->query("//body//*/text()"); 

使我有不同的文本內容,但省略了HTML標籤。

當我只是這樣做:

$res=$xpath->query("//body//*"); 

我得到重複的文字,每一個標籤星座:「世界」例如爲:會出現3次, 一次爲「身體」,一次爲「h1」,一次爲「b」,但我似乎無法獲得文本實際重複的信息。只是檢查重複的文本是 不夠充分,因爲重複的文本有時只是以前的文本的子串,或者網站 可能包含真正的重複文本,然後將丟棄這是錯誤的。

我該如何解決這個問題?

非常感謝!

托馬斯

+0

我認爲你需要爲這個XQuery的。無論如何,在HTML上使用XML技術並不好。該html可能不是格式良好的,因此,你會得到解析錯誤。 –

+3

@AurelioDeRosa DOM可以解析破損的HTML – Gordon

+0

您還沒有接受答案。你能否澄清你在回答中尋找什麼,以及爲什麼給出的答案不能令你滿意。 – Gordon

回答

1

在你的示例代碼,$res=$xpath->query("//body//*/text()")DOMText節點的DOMNodeList。對於每個DOMText,可以通過parentNode屬性訪問包含元素。

+0

啊,好主意,我只是試過了,實際上我可以訪問parentNode,所以我可以手動迭代所有「更高」的節點來獲取周圍的標籤。唯一的缺點可能是性能。也許還有另一種方法可以在一次運行中完成,因此效率可能更高。但是,儘管如此,我想給你一個好主意,我現在要測試它,看看它的表現。 – Thomas

5

您可以在DOMText節點parentNodes迭代:

$dom = new DOMDocument; 
$dom->loadHTML($html); 
$xpath = new DOMXPath($dom); 
$textNodes = array(); 
foreach($xpath->query('/html/body//text()') as $i => $textNode) { 
    $textNodes[$i] = array(
     'text' => $textNode->nodeValue, 
     'parents' => array() 
    ); 
    for (
     $currentNode = $textNode->parentNode; 
     $currentNode->parentNode; 
     $currentNode = $currentNode->parentNode 
    ) { 
     $textNodes[$i]['parents'][] = $currentNode->nodeName; 
    } 
} 
print_r($textNodes); 

demo

注意loadHTML將增加隱含的元素,例如它將添加使用XPath時必須考慮的html和head元素。另外請注意,用於格式化的任何空格都被視爲DOMText,因此您可能會獲得比您期望的更多的元素。如果你只想要查詢非空一個DOMText節點使用

/html/body//text()[normalize-space(.) != ""] 

demo

+0

哇,謝謝你編程的演示,它的作品!非常感謝,還有關於空白的進一步想法!非常感謝你的幫助和努力! – Thomas