C#实现XML的value3列阈值查找及空引用警告修复
问题
给定如下XML数据:
<Row> <Cell ss:StyleID="s16"><Data ss:Type="String">Name</Data></Cell> <Cell ss:StyleID="s16"><Data ss:Type="String">value1</Data></Cell> <Cell ss:StyleID="s16"><Data ss:Type="String">value2</Data></Cell> <Cell ss:StyleID="s17"><Data ss:Type="String">value3</Data></Cell> </Row> <Row> <Cell ss:StyleID="s18"><Data ss:Type="String">B</Data></Cell> <Cell ss:StyleID="s18"><Data ss:Type="Number">31</Data></Cell> <Cell ss:StyleID="s18"><Data ss:Type="Number">47</Data></Cell> <Cell ss:StyleID="s19"><Data ss:Type="Number">148</Data></Cell> </Row> <Row> <Cell ss:StyleID="s18"><Data ss:Type="String">C</Data></Cell> <Cell ss:StyleID="s18"><Data ss:Type="Number">40</Data></Cell> <Cell ss:StyleID="s18"><Data ss:Type="Number">78</Data></Cell> <Cell ss:StyleID="s19"><Data ss:Type="Number">312</Data></Cell> </Row> <Row>
需求:在C#中设置阈值200,查找value3列(第4个单元格)中首个大于该阈值的行(对应数据为C,40,78,312),并将该行各单元格值存入独立变量。
现有代码存在「Dereference of a possibly null reference」「Converting null literal or possible null value to non-nullable type」警告,原代码如下:
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Properties.Resources.Data); double threshold=200; XmlNodeList rows = xmlDoc.SelectNodes("//Row[Cell[4][number(Data) > " + threshold + "]]"); foreach (XmlNode row in rows) { XmlNodeList cells = row.SelectNodes("Cell/Data"); string cell1 = cells[0].InnerText; double cell2 = double.Parse(cells[1].InnerText); double cell3 = double.Parse(cells[2].InnerText); }
解决方案
核心优化点
- 直接获取首个匹配行,避免不必要的遍历
- 增加全链路空引用检查,消除警告
- 使用安全的数值解析方法,避免格式异常
- 优化字符串拼接方式,提升代码可读性
修正后的完整代码
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Properties.Resources.Data); double threshold = 200; // 查找符合条件的行并取首个结果 XmlNodeList matchingRows = xmlDoc.SelectNodes($"//Row[Cell[4][number(Data) > {threshold}]]"); XmlNode targetRow = matchingRows?.Cast<XmlNode>().FirstOrDefault(); if (targetRow != null) { XmlNodeList cellDatas = targetRow.SelectNodes("Cell/Data"); // 确保单元格数量足够 if (cellDatas != null && cellDatas.Count >= 4) { // 处理字符串类型单元格,空值兜底为空字符串 string cell1 = cellDatas[0]?.InnerText ?? string.Empty; // 安全解析数值类型单元格,解析失败时返回默认值0 double.TryParse(cellDatas[1]?.InnerText, out double cell2); double.TryParse(cellDatas[2]?.InnerText, out double cell3); double.TryParse(cellDatas[3]?.InnerText, out double cell4); // value3列对应第4个单元格 // 可在此处使用变量执行后续逻辑 Console.WriteLine($"目标行数据:{cell1}, {cell2}, {cell3}, {cell4}"); } }
关键细节说明
- XPath查询优化:用字符串插值替代拼接,简化代码同时避免语法错误
- 首个行获取:通过
Cast<XmlNode>().FirstOrDefault()直接提取第一个匹配行,精准满足需求 - 空引用防护:对
matchingRows、targetRow、cellDatas及每个单元格节点都做了空值校验,彻底解决警告 - 安全解析:
double.TryParse在解析失败时不会抛出异常,提升代码健壮性
内容的提问来源于stack exchange,提问作者mjkp6654
相关产品推荐
相关产品推荐

