2012-01-23 43 views
1

嗨,我剛剛在這個網站上註冊,因爲我需要一些幫助。HtmlAgilityPack |錯誤地檢索表節點

我想從nyaa.eu網站獲得結果。

基本上是:

  • 表節點稱爲<table class="tlist">
  • 每一行節點被稱爲<tr class="tlistrow">有時也很'信任tlistrow'
  • 我嘗試檢索的節點是:<td class="tlistname"> <td class="tlistsize"> <td class="tlistsn"> and <td class="tlistln">

首先,我正在檢索一張表格,包含了所有關於種子的信息:

HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']"); 

所以,接下來的事情就是獲取所有的行包含在它的類屬性「tlistrow」:

HtmlNodeCollection hncRows = hnTable.SelectNodes("//tr[contains(@class,'tlistrow')]"); 

最後的問題是,當我讀到的每一個節點它總是同一個:

foreach (HtmlNode row in hncRows) 
{ 
    foreach (HtmlNode child in row.ChildNodes) 
    { 
     if (child.SelectSingleNode("//td[@class='tlistname']") != null) 
     { 
      MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText); 
      break; 
     } 
    } 
} 

在MessageBox顯示的文本始終是相同的,它看起來像只選擇一個節點多次。

我該如何解決這個問題,或者如果我做錯了什麼,請糾正我。

回答

1
foreach (HtmlNode child in row.ChildNodes) 
    { 
     if (child.SelectSingleNode("//td[@class='tlistname']") != null) 
     { 
      MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText); 
      break; 
     } 
    } 

您需要了解相對XPath表達式和絕對XPath表達式之間的差異。

一個相對XPath表達式被評估爲(具有作爲初始上下文節點的)XML文檔中的特定節點。

針對整個XML文檔(具有作爲文檔節點的初始上下文節點)評估絕對XPath表達式。

任何以字符/開頭的XPath表達式都是絕對XPath表達式。

根據所提供的代碼,您希望使用帶有初始上下文節點的相對XPath表達式,並將其包含在名爲child的變量中。

的問題是表達你使用:

//td[@class='tlistname'] 

開始與/,因此是絕對的XPath表達式。

此,傳遞給SelectSingleNode()方法總是選擇整個XML文檔中的第一td元件,具有class屬性與字符串值"tlistname."

:使用相對XPath表達式,如:

.//td[@class='tlistname'] 
+0

耶,這是我見過的最簡單的修復。非常感謝!我其實從來沒有讀過XPath,所以這就是爲什麼我失敗了...... –

+0

@KonradPiesiak:不客氣。 XPath是一個非常神奇,強大和優雅的語言(這些品質在版本2.0和3.0中都有所增長)。它值得系統學習。 –

0

表達式中的//XPath將在文檔中的任何位置查找匹配項。刪除,當你不需要它。

所以,你可以試試:

HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']"); 
HtmlNodeCollection hncRows = hnTable.SelectNodes("/tr[contains(@class,'tlistrow')]"); 
foreach (HtmlNode row in hncRows) 
{ 
    foreach (HtmlNode child in row.ChildNodes) 
    { 
     if (child.SelectSingleNode("/td[@class='tlistname']") != null) 
     { 
      MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("/td[@class='tlistname']").InnerText); 
      break; 
     } 
    } 
}