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



我正在尝试遍历网页(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)
 {
...

代码逻辑有点不对劲。使用原始代码,如果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
}

最新更新