次のことを考えると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を使用してを作成します。
Dim dt = new DataTable()
For Each h in grouped.Select(Function(g) g.Key)
dt.Columns.Add(h)
Next
ここで、を埋めるにはDataTable
、各グループに1つの列のデータが含まれているため、グループを「ローテーション」する必要がありますが、各行のデータが必要です。ちょっとしたヘルパーメソッドを使ってみましょう
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
ようになります: