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);
当然,只有当td
是tr
的直接孩子时才会有效,但它们应该是,对吧?
编辑:
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 + "
"); } } }
我相信它可以写得比这更好,但它现在对我有用。