Html Agility Pack循环遍历表行和列

我有一张这样的桌子

Name Age
Mario Age: 78
Jane Age: 67
James Age: 92

并希望使用HTML Agility Pack来解析它。 我试过这段代码无济于事:

 foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr")) { foreach (HtmlNode col in row.SelectNodes("//td")) { Response.Write(col.InnerText); } } 

我究竟做错了什么?

我运行代码并且它只显示名称 ,这是正确的,因为Ages是使用无效的HTML定义的:

(可能是拼写错误)。

顺便说一句,代码可以简化为只有一个循环:

 foreach (var cell in doc.DocumentNode.SelectNodes("//table[@id='table2']/tr/td")) { Response.Write(cell.InnerText); } 

这是我以前测试的代码: http : //pastebin.com/euzhUAAh

你为什么不直接选择td

 foreach (HtmlNode col in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr//td")) Response.Write(col.InnerText); 

或者,如果您确实需要单独进行某些其他处理,请删除//并执行:

 foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr")) foreach (HtmlNode col in row.SelectNodes("td")) Response.Write(col.InnerText); 

当然,只有当tdtr的直接孩子时才会有效,但它们应该是,对吧?


编辑:

 var cols = doc.DocumentNode.SelectNodes("//table[@id='table2']//tr//td"); for (int ii = 0; ii < cols.Count; ii=ii+2) { string name = cols[ii].InnerText.Trim(); int age = int.Parse(cols[ii+1].InnerText.Split(' ')[1]); } 

使用LINQ可能有更令人印象深刻的方法。

我必须提供完整的xpath。 我从@Coda( https://stackoverflow.com/a/3104048/1238850 )的建议中使用Firebug得到了完整的xpath,我最终得到了这段代码:

 foreach (HtmlNode row in doc.DocumentNode.SelectNodes("/html/body/table/tbody/tr/td/table[@id='table2']/tbody/tr")) { HtmlNodeCollection cells = row.SelectNodes("td"); for (int i = 0; i < cells.Count; ++i) { if (i == 0) { Response.Write("Person Name : " + cells[i].InnerText + "
"); } else { Response.Write("Other attributes are: " + cells[i].InnerText + "
"); } } }

我相信它可以写得比这更好,但它现在对我有用。