我正在尝试遍历网页上的可变长度表的每一行(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)
{
...
答案 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
}