2012-01-23 44 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; 
     } 
    } 
}