通过HTML<th>标签循环为DataTable添加列时遇空引用异常求解
从HTML的提取内容给DataTable添加列时触发空引用异常
我尝试用foreach循环从HTML的标签提取文本,为C#的DataTable添加列,但运行时出现空引用异常。已确认HTML中没有空的标签,相关代码和HTML片段如下:
原C#代码
DataTable dt = new DataTable(); int i = 0; HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]"); foreach (var row in table.SelectNodes("tr")) { var headers = row.SelectNodes("th"); foreach (var el in headers) { if (headers != null) { dt.Columns.Add(headers[i].InnerText); i++; } } }
对应HTML片段
<table> <colgroup><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/></colgroup> <tr><th>id</th><th>inserted_at</th><th>DisplayName</th><th>DistinguishedName</th><th>Enabled</th><th>GivenName</th><th>HomeDirectory</th><th>Manager</th><th>Name</th><th>ObjectClass</th><th>ObjectGUID</th><th>SamAccountName</th><th>Surname</th><th>UserPrincipalName</th><th>RowError</th><th>RowState</th><th>Table</th><th>ItemArray</th><th>HasErrors</th></tr>
问题根源
- 空引用触发点:当遍历到不含的行时,
row.SelectNodes("th")返回null,此时直接执行foreach (var el in headers)会抛出空引用异常——你把headers != null的判断放在了内层循环里,时机太晚。 - 逻辑冗余与风险:内层循环中用
headers[i].InnerText完全多余,既然已经遍历headers的每个元素el,直接用el.InnerText即可;全局变量i会在后续行遍历中持续累加,极易导致数组越界。
修正后的代码
方案1:直接定位表头行(推荐)
直接找到第一个包含的,避免遍历所有行:
DataTable dt = new DataTable(); HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]"); // 定位包含<th>的表头行 var headerRow = table?.SelectSingleNode("tr[th]"); if (headerRow != null) { var headers = headerRow.SelectNodes("th"); if (headers != null) { foreach (var el in headers) { // 用Trim()去除<th>文本前后可能的空白字符 dt.Columns.Add(el.InnerText.Trim()); } } }
方案2:遍历所有行(兼容表头非第一行的情况)
如果不确定表头位置,遍历所有行,找到表头后立即退出循环:
DataTable dt = new DataTable(); HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]"); if (table != null) { var rows = table.SelectNodes("tr"); if (rows != null) { foreach (var row in rows) { var headers = row.SelectNodes("th"); // 先判断headers非空,再处理 if (headers != null) { foreach (var el in headers) { dt.Columns.Add(el.InnerText.Trim()); } // 找到表头后退出循环,不再处理数据行 break; } } } }
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

