C# 从HTML表存储数据的最佳方式是什么?
我目前正在使用CsQuery阅读一个HTML文档。这个文档有几个HTML表,我需要在保存结构的同时读入数据。目前,我只是有一个字符串列表。这是一个表列表,其中包含一个行列表,该行列表包含一个单元格列表,该单元格以字符串形式包含内容C# 从HTML表存储数据的最佳方式是什么?,c#,html,csquery,C#,Html,Csquery,我目前正在使用CsQuery阅读一个HTML文档。这个文档有几个HTML表,我需要在保存结构的同时读入数据。目前,我只是有一个字符串列表。这是一个表列表,其中包含一个行列表,该行列表包含一个单元格列表,该单元格以字符串形式包含内容 List<List<List<string>>> page_tables = document_div.Cq().Find("TABLE") .Select(table => table.Cq().Find("TR"
List<List<List<string>>> page_tables = document_div.Cq().Find("TABLE")
.Select(table => table.Cq().Find("TR")
.Select(tr => tr.Cq().Find("td")
.Select(td => td.InnerHTML).ToList())
.ToList())
.ToList();
List page\u tables=document\u div.Cq().Find(“表”)
.Select(table=>table.Cq().Find(“TR”)
.Select(tr=>tr.Cq().Find(“td”)
.Select(td=>td.InnerHTML.ToList())
.ToList())
.ToList();
有没有更好的方法来存储这些数据,以便我可以轻松访问特定的表、特定的行和单元格?我正在写几个方法来处理这个page_tables对象,所以我需要先确定它的公式
有没有更好的方法来存储这些数据,以便我可以轻松访问特定的表、特定的行和单元格
在大多数情况下,格式良好的HTML非常适合XML结构,因此可以将其存储为XML文档。LINQ到XML将使查询变得非常简单
XDocument doc=XDocument.parse(“…”);
var cellData=doc.substant(“td”)。选择(x=>x.Value);
根据这些评论,我觉得有必要指出,还有一些其他情况可能会出现这种情况,例如
- 当使用像
这样的HTML编码内容时 - 使用不需要结束标记的有效HTML,例如
XDocument doc=XDocument.parse(“…”);
var cellData=doc.substant(“td”)。选择(x=>x.Value);
根据这些评论,我觉得有必要指出,还有一些其他情况可能会出现这种情况,例如
- 当使用像
这样的HTML编码内容时 - 使用不需要结束标记的有效HTML,例如
XDocument doc=XDocument.parse(“…”);
var cellData=doc.substant(“td”)。选择(x=>x.Value);
根据这些评论,我觉得有必要指出,还有一些其他情况可能会出现这种情况,例如
- 当使用像
这样的HTML编码内容时 - 使用不需要结束标记的有效HTML,例如
XDocument doc=XDocument.parse(“…”);
var cellData=doc.substant(“td”)。选择(x=>x.Value);
根据这些评论,我觉得有必要指出,还有一些其他情况可能会出现这种情况,例如
- 当使用像
这样的HTML编码内容时 - 使用不需要结束标记的有效HTML,例如
总而言之,这绝对不是最健壮的方法,但是,如果您能够确保所解析的HTML符合要求,那么这将是一个非常好的解决方案。您可以完全面向对象并编写一些模型类:
// Code kept short, minimal ctors
public class Cell
{
public string Content {get;set;}
public Cell() { this.Content = string.Empty; }
}
public class Row
{
public List<Cell> Cells {get;set;}
public Row() { this.Cells = new List<Cell>(); }
}
public class Table
{
public List<Row> Rows {get;set;}
public Table() { this.Rows = new List<Row>(); }
}
//代码保持简短,最小的系数
公共类单元
{
公共字符串内容{get;set;}
公共单元格(){this.Content=string.Empty;}
}
公共类行
{
公共列表单元格{get;set;}
public Row(){this.Cells=new List();}
}
公共类表
{
公共列表行{get;set;}
公共表(){this.Rows=new List();}
}
然后把它们填满,例如:
var tables = new List<Table>();
foreach(var table in document_div.Cq().Find("TABLE"))
{
var t = new Table();
foreach(var tr in table.Cq().Find("TR"))
{
var r = new Row();
foreach(var td in tr.Cq().Find("td"))
{
var c = new Cell();
c.Contents = td.InnerHTML;
r.Cells.Add(c);
}
t.Rows.Add(r);
}
tables.Add(t);
}
// Assuming the HTML was correct, now you have a cleanly organized
// class structure representing the tables!
var aTable = tables.First();
var firstRow = aTable.Rows.First();
var firstCell = firstRow.Cells.First();
var firstCellContents = firstCell.Contents;
...
var tables=newlist();
foreach(文档_div.Cq().Find(“表”)中的var表)
{
var t=新表();
foreach(表.Cq()中的var tr.Find(“tr”))
{
var r=新行();
foreach(tr.Cq().Find(“td”)中的var td)
{
var c=新单元();
c、 Contents=td.InnerHTML;
r、 添加(c);
}
t、 行。添加(r);
}
表.添加(t);
}
//假设HTML是正确的,现在您有了一个干净的组织
//表示表的类结构!
var aTable=tables.First();
var firstRow=aTable.Rows.First();
var firstCell=firstRow.Cells.First();
var firstCellContents=firstCell.Contents;
...
我可能会选择这种方法,因为我总是希望确切地知道我的数据是什么样的,特别是当我从外部/不安全的数据进行解析时
var tables = new List<Table>();
foreach(var table in document_div.Cq().Find("TABLE"))
{
var t = new Table();
foreach(var tr in table.Cq().Find("TR"))
{
var r = new Row();
foreach(var td in tr.Cq().Find("td"))
{
var c = new Cell();
c.Contents = td.InnerHTML;
r.Cells.Add(c);
}
t.Rows.Add(r);
}
tables.Add(t);
}
// Assuming the HTML was correct, now you have a cleanly organized
// class structure representing the tables!
var aTable = tables.First();
var firstRow = aTable.Rows.First();
var firstCell = firstRow.Cells.First();
var firstCellContents = firstCell.Contents;
...
<table>
<tr><td>1</td><td>Bob</td></tr>
<tr><td>2</td><td>Joe</td></tr>
</table>
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
HtmlDocument doc = new HtmlDocument();
doc.Load("index.html");
var users = from r in doc.DocumentNode.SelectNodes("//table/tr")
let cells = r.SelectNodes("td")
select new User
{
Id = Int32.Parse(cells[0].InnerText),
Name = cells[1].InnerText
};
// NOTE: you can check cells count before accessing them by index
var usersDictionary = users.ToDictionary(u => u.Id);
// Getting user by id
var user = usersDictionary[2];
// now you can read user.Name