鉴于以下html
Dim t = <table class='Seller' id='MyTable'>
<tr>
<th>FooColumn</th>
<td>Foo</td>
<td>Another Foo</td>
</tr>
<tr>
<th>BarColumn</th>
<td>Bar</td>
<td>Another Bar</td>
</tr>
<tr>
<th>ThirdColumn</th>
<td>Third</td>
<td>Another Third</td>
</tr>
</table>
Dim htmldoc = New HtmlAgilityPack.HtmlDocument()
htmldoc.LoadHtml(t.ToString())
和你的查询
Dim q = From table In htmldoc.DocumentNode.SelectNodes("//table[@class='Seller']")
From row In table.SelectNodes("tr")
From header In row.SelectNodes("th")
From cell In row.SelectNodes("td")
Select New With {.Table = table.Id, .CellText = cell.InnerText, .headerText = header.InnerText}
您可以使用GroupBy
或ToLookup
按列对对象进行分组:
Dim grouped = q.ToLookup(Function(a) a.headerText)
并使用此分组创建DataTable
具有适当DataColumn
s 的 a:
Dim dt = new DataTable()
For Each h in grouped.Select(Function(g) g.Key)
dt.Columns.Add(h)
Next
现在,为了填充DataTable
,您必须“旋转”分组,因为每个组包含一列的数据,但我们想要每一行的数据。让我们使用一个小助手方法
Function Rotate(Of T, TR)(source As IEnumerable(Of IEnumerable(Of T)),
selector As Func(Of IEnumerable(Of T), IEnumerable(Of TR))) As IEnumerable(Of IEnumerable(Of TR))
Dim result = new List(Of IEnumerable(Of TR))
Dim enums = source.Select(Function(e) e.GetEnumerator()).ToArray()
While enums.All(Function(e) e.MoveNext())
result.Add(selector(enums.Select(Function(e) e.Current)).ToArray())
End While
Return result
End Function
填充DataTable
.
For Each rrow in Rotate(grouped, Function(row) row.Select(Function(e) e.CellText))
dt.Rows.Add(rrow.ToArray())
Next
现在DataTable
将看起来像这样: