C#解析RSS源内嵌表格时抛出NullReferenceException求助
空引用异常根因定位与修正方案
触发异常的核心问题点
- 定位表格节点的逻辑完全不适配RSS的结构
加载的RSS本质是标准XML文档,目标HTML表格是被包裹在CDATA段内,挂在<item>/<description>节点下的,不是直接暴露在文档根层级的。直接全局执行SelectSingleNode("//table")大概率返回null,后续对null对象调用SelectNodes方法时,就会直接抛出NullReferenceException。 - XPath相对路径写法完全错误
按照XPath规范,只要查询路径以//开头,就会从整个文档的根节点开始做全量匹配,不会以当前调用方法的DOM节点为查询起点。
比如已经拿到了某一个row节点,写row.SelectNodes("//td"),实际拿到的是整个文档范围内所有的td节点,根本不是当前行内部的单元格。如果全局范围内没匹配到对应节点,SelectNodes会返回null,后续操作就会触发空引用。 - 忽略了HtmlAgilityPack的返回值特性
该组件的SelectNodes方法在无匹配结果时返回的是null,而非空集合。哪怕前面对rows做了非空判断,进入循环后如果查cells没做判空,一旦匹配不到就会直接抛异常。
可直接运行的修正代码
public void readRss() { string Url = "mylink.com"; HtmlWeb web = new HtmlWeb(); HtmlDocument doc = web.Load(Url); // 调整匹配路径,定位description下CDATA块里的表格 var table = doc.DocumentNode.SelectSingleNode("//item/description//table"); // 前置非空判断,避免对null节点操作 if (table == null) { Console.WriteLine("未匹配到目标表格,退出解析"); return; } // 以table为起点,用.//匹配下属所有tr节点,不再用全局匹配的// var rows = table.SelectNodes(".//tr"); if (rows != null && rows.Count > 0) { foreach (var row in rows) { // 同样以当前row为起点,匹配下属td var cells = row.SelectNodes(".//td"); // 单元格节点单独做非空判断 if (cells == null || cells.Count == 0) continue; // 提取文本的逻辑 foreach (var cell in cells) { var cellText = cell.InnerText.Trim(); // 原有业务处理逻辑 } } } }
额外排查提醒
- 给出的XML样例本身存在结构瑕疵:第二个
<tr>标签没有闭合,虽然HtmlAgilityPack容错能力较强能自动补全,但如果遇到严格的XML解析校验,很可能出现节点层级识别错误。 - 所有SelectSingleNode、SelectNodes的返回值都要做非空判断,不要默认目标节点一定存在——RSS源的结构随时可能因为站点调整发生变化,硬编码的匹配路径很容易因为结构偏移返回null。
- 如果调整路径后还是找不到table节点,说明HtmlAgilityPack把CDATA段的内容识别为纯文本节点,没有自动解析成DOM结构。这时候可以先提取CDATA节点的InnerText,把里面包裹的HTML字符串单独传给新的HtmlDocument实例调用LoadHtml解析,再执行后续表格查找逻辑。
内容的提问来源于stack exchange,提问作者Tabris
相关产品推荐
相关产品推荐

