Estoy utilizando la siguiente consulta para analizar datos de la tabla html.
Dim q = From table In htmldoc.DocumentNode.SelectNodes("//table[@class='Seller']").Cast(Of HtmlNode)()
From row In table.SelectNodes("tr").Cast(Of HtmlNode)()
From header In row.SelectNodes("th").Cast(Of HtmlNode)()
From cell In row.SelectNodes("td").Cast(Of HtmlNode)()
Select New With {Key .Table = table.Id, Key .CellText = cell.InnerText, Key .headerText = header.InnerText}
¿Cómo puedo usar para cada bucle, cómo puedo completar esto en una tabla de datos?
Primero crearía columnas con los datos del encabezado y luego utilizaría un anidado para cada bucle para completar los datos de las celdas en la tabla, pero no estoy seguro de cómo hacerlo. ¿Hay algún cambio sugerido en la consulta LINQ anterior?
Nota : La página html contiene solo una tabla siempre.
Dado el siguiente 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())
y tu consulta
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}
puedes usar GroupBy
o ToLookup
para agrupar los objetos por columnas:
Dim grouped = q.ToLookup(Function(a) a.headerText)
y use esta agrupación para crear un DataTable
con los DataColumn
s apropiados:
Dim dt = new DataTable()
For Each h in grouped.Select(Function(g) g.Key)
dt.Columns.Add(h)
Next
Ahora, para completar el DataTable
, debe "rotar" la agrupación, ya que cada grupo contiene los datos de una columna, pero queremos los datos de cada fila. Usemos un pequeño método de ayuda.
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
para llenar el DataTable
.
For Each rrow in Rotate(grouped, Function(row) row.Select(Function(e) e.CellText))
dt.Rows.Add(rrow.ToArray())
Next
Y ahora el DataTable
se verá así: