当Xpath查询返回空引用html敏捷包时,如何终止while循环

时间:2014-04-05 19:51:28

标签: xpath html-agility-pack nullreferenceexception

我正在尝试遍历网页上的可变长度表的每一行(http://www.oddschecker.com/golf/the-masters/winner)并提取一些数据

问题是我似乎无法捕获空引用并终止循环而不抛出异常!

int i = 1;
bool test = string.IsNullOrEmpty(doc.DocumentNode.SelectNodes(String.Format("//*[@id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText);

while (test != true)
{
    string name = doc.DocumentNode.SelectNodes(String.Format("//*[@id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
    //extract data
    i++;
}

try-catch语句也没有捕获它:

bool test = false;
try
{
     string golfersName = doc.DocumentNode.SelectNodes(String.Format("//*[@id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
 }
 catch
 {
      test = true;
 }

 while (test != true)
 {
...

1 个答案:

答案 0 :(得分:1)

代码逻辑有点偏。使用原始代码,如果test评估true,则循环永远不会终止。您似乎想要在每次循环迭代中进行检查,而不是仅在开始时进行一次检查。

无论如何,还有更好的方法。您可以选择所有相关节点而不指定每个<tr>索引,并使用foreach循环遍历节点集:

var nodes = doc.DocumentNode.SelectNodes("//*[@id='t1']/tr/td[3]/a[2]");
foreach(HtmlNode node in nodes)
{
    string name = node.InnerText;
    //extract data
}

或使用for循环而不是foreach,如果“提取数据”过程需要每个节点的索引:

for(i=1; i<=nodes.Count; i++)
{
    //array index starts from 0, unlike XPath element index
    string name = nodes[i-1].InnerText;
    //extract data
}

旁注:要查询单个元素,您可以使用SelectSingleNode("...")代替SelectNodes("...")[0]。如果没有节点符合XPath标准,则两个方法都返回null,因此您可以检查返回的原始值而不是InnerText属性以避免异常:

var node = doc.DocumentNode.SelectSingleNode("...");
if(node != null)
{
    //do something
}