我正在尝试将表格从 html 文件解析为数据集。我使用 vb.net 创建了一个 Windows 应用程序,我正在使用以下函数:
Public Function GetDataSet(ByVal strWebFilePath As String) As DataSet
Dim html As String = System.IO.File.ReadAllText(strWebFilePath)
html = WebUtility.HtmlDecode(html)
Dim dsHtml As New DataSet
Dim htmldoc As New HtmlAgilityPack.HtmlDocument
htmldoc.LoadHtml(html)
Dim tables = htmldoc.DocumentNode.SelectNodes("//table//tr") _
.GroupBy(Function(x) x.Ancestors("table").First())
For i As Integer = 0 To tables.Count - 1
Dim rows = tables(i).ToList()
dsHtml.Tables.Add(String.Format("Table {0}", i))
Dim headers = rows(0).Elements("th").Select(Function(x) x.InnerText.Trim).ToList()
If headers.Count > 0 Then
For Each Hr In headers
dsHtml.Tables(i).Columns.Add(Hr)
Next
For j As Integer = 1 To rows.Count - 1
Dim row = rows(j)
Dim dr = row.Elements("td").Select(Function(x) x.InnerText.Trim).ToArray()
dsHtml.Tables(i).Rows.Add(dr)
Next
Else
headers = rows(0).Elements("td").Select(Function(x) x.InnerText.Trim).ToList()
For ColumnIndex As Integer = 0 To headers.Count - 1
dsHtml.Tables(i).Columns.Add("F" & ColumnIndex.ToString)
Next
For j As Integer = 0 To rows.Count - 1
Dim row = rows(j)
Dim dr = row.Elements("td").Select(Function(x) x.InnerText.Trim).ToArray()
dsHtml.Tables(i).Rows.Add(dr)
Next
End If
Next
Return dsHtml
End Function
一切正常,直到我解析 html 表,它的第一行包含一个具有 colspan=2
的列(第一行被认为是标题,即使它不包含 <th>
)。所以它抛出这个异常:
An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll Additional information: Input array is longer than the number of columns in this table.
考虑这个表格示例:
<table>
<tr><td colspan=2>Links</td></tr>
<tr><td>1</td><td>www.stackoverflow.com</td></tr>
<tr><td>2</td><td>www.sqlservercentral.com</td></tr>
<tr><td>3</td><td>www.dba.stackexchange.com/</td></tr>
</table>
有没有办法将第一行分成两列:
- 第一个包含
Links
- 第二个包含自动生成的值(即:
Col1
)
最佳答案
您需要一些关于如何解决列跨度、行跨度、缺失单元格、额外单元格、单元格中的值不一致等问题的约定。通常很难将 html 表解析为 DataTable
不知道数据表的结构。
在这个答案中,我将重点关注标题上的列跨度。
有什么问题?
你依赖<th>
排在第一位 <tr>
并根据找到的 <th>
添加列到数据表中.所以如果你有这样的表:
<table>
<tr>
<th colspan="2">A</th>
<th>B</th>
</tr>
<tr>
<td>1</td>
<td>11</td>
<td>111</td>
</tr>
</table>
然后您假设您有 2 列,并且在添加行时,由于每行中有 3 个元素,您会收到异常。
我该如何解决这个问题?
这里我决定转换<th colspan="n">C</th>
到名称为 C1
的 n 列, C2
, ... , Cn
.
Dim headers = rows(0).Elements("th").Select(Function(x) _
New With
{
.Name = x.InnerText.Trim,
.Count = If(x.Attributes("colspan") Is Nothing, _
1, Integer.Parse(x.Attributes("colspan").Value))
}).ToList()
然后在向数据表中添加列时:
For Each Hr In headers
For index = 1 To Hr.Count
Dim postFix = If(Hr.Count > 1, index.ToString(), "")
dsHtml.Tables(i).Columns.Add(Hr.Name & postFix)
Next
Next
关于html - 将 html 表解析为数据集时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40852390/