Html敏捷包循环遍历表的行和列
本文关键字:遍历 循环 包循环 Html | 更新日期: 2023-09-27 18:00:07
我有一个类似的表
<table border="0" cellpadding="0" cellspacing="0" id="table2">
<tr>
<th>Name
</th>
<th>Age
</th>
</tr>
<tr>
<td>Mario
</td>
<th>Age: 78
</td>
</tr>
<tr>
<td>Jane
</td>
<td>Age: 67
</td>
</tr>
<tr>
<td>James
</td>
<th>Age: 92
</td>
</tr>
</table>
我想使用HTML敏捷包来解析它。我尝试过这个代码,但没有成功:
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr"))
{
foreach (HtmlNode col in row.SelectNodes("//td"))
{
Response.Write(col.InnerText);
}
}
我做错了什么?
为什么不直接选择td
?
foreach (HtmlNode col in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr//td"))
Response.Write(col.InnerText);
或者,如果您确实需要单独使用tr
进行其他处理,请删除//
并执行:
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可能还有一种更令人印象深刻的方法。
我已经运行了代码,它只显示名称,这是正确的,因为年龄是使用无效的HTML:<th></td>
定义的(可能是打字错误)。
顺便说一下,代码可以简化为只有一个循环:
foreach (var cell in doc.DocumentNode.SelectNodes("//table[@id='table2']/tr/td"))
{
Response.Write(cell.InnerText);
}
以下是我用来测试的代码:http://pastebin.com/euzhUAAh
我必须提供完整的xpath。根据@Coda的建议,我使用Firebug获得了完整的xpath(https://stackoverflow.com/a/3104048/1238850)最后我得到了这个代码:
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 + "<br>"); }
else {
Response.Write("Other attributes are: " + cells[i].InnerText + "<br>");
}
}
}
我相信它可以写得比这更好,但它现在对我有效。
我用这个做了同样的项目:
private List<PhrasalVerb> ExtractVerbsFromMainPage(string content)
{
var verbs =new List<PhrasalVerb>(); ;
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(content);
var rows = doc.DocumentNode.SelectNodes("//table[@class='idioms-table']//tr");
rows.RemoveAt(0); //remove header
foreach (var row in rows)
{
var cols = row.SelectNodes("td");
verbs.Add(new PhrasalVerb {
Uid = Guid.NewGuid(),
Name = cols[0].InnerHtml,
Definition = cols[1].InnerText,
Count =int.TryParse(cols[2].InnerText,out _) == true ? Convert.ToInt32(cols[2].InnerText) : 0
});
}
return verbs;
}
private List<Table1> getTable1Data(string result)
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(result);
var table1 = htmlDoc.DocumentNode.SelectNodes("//table").First();
var tbody = table1.ChildNodes["tbody"];
var lst = new List<Table1>();
foreach (var row in tbody.ChildNodes.Where(r => r.Name == "tr"))
{
var tbl1 = new Table1();
var columnsArray = row.ChildNodes.Where(c => c.Name == "td").ToArray();
for (int i = 0; i < columnsArray.Length; i++)
{
if (i == 0)
tbl1.Course = columnsArray[i].InnerText.Trim();
if (i == 1)
tbl1.Count = columnsArray[i].InnerText.Trim();
if (i == 2)
tbl1.Correct = columnsArray[i].InnerText.Trim();
}
lst.Add(tbl1);
}
return lst;
}
public class Table1
{
public string Course { get; set; }
public string Count { get; set; }
public string Correct { get; set; }
}