XmlDocument解析XML属性值触发空引用异常的修复方案咨询
问题描述
异常情况
运行以下C#代码时触发System.NullReferenceException,异常出现在为return_values[0]赋值的行:
public string[] UnpackXML(string xml_string) { string response = xml_string; string[] return_values = new string[6]; XmlDocument xml = new XmlDocument(); xml.LoadXml(response); return_values[0] = xml.GetElementsByTagName("meas name=\"mt1\"")[0].InnerText.ToString(); return_values[1] = xml.GetElementsByTagName("meas name=\"mt2\"")[0].InnerText.ToString(); return_values[2] = xml.GetElementsByTagName("meas name=\"mt3\"")[0].InnerText.ToString(); return_values[3] = xml.GetElementsByTagName("meas name=\"mt4\"")[0].InnerText.ToString(); return_values[4] = xml.GetElementsByTagName("meas name=\"mt5\"")[0].InnerText.ToString(); return_values[5] = xml.GetElementsByTagName("meas name=\"mt6\"")[0].InnerText.ToString(); return return_values; }
System.NullReferenceException: 'Object reference not set to an instance of an object.'
输入XML格式
API返回的XML字符串格式如下:
<response location='location1'> <meas name='mt1'>14</meas> <meas name='mt2'>23</meas> <meas name='mt3'>65</meas> <meas name='mt4'>31</meas> <meas name='mt6'>32</meas> </response>
需求:将XML中指定name属性的<meas>元素内容存入数组,无需遍历属性逐一校验,直接定位元素。
修复方案
错误原因
GetElementsByTagName方法仅根据标签名称(这里是meas)查找元素,无法识别带属性的字符串meas name="mt1",导致返回的节点集合为空,访问[0]时触发空引用异常。同时输入XML中不存在name="mt5"的元素,即使前面的逻辑正确,这一行也会报错。
方法1:使用XmlDocument + XPath直接定位
通过XPath表达式可以直接根据元素标签和属性值定位节点,无需遍历:
public string[] UnpackXML(string xml_string) { string[] return_values = new string[6]; XmlDocument xml = new XmlDocument(); xml.LoadXml(xml_string); // 用XPath定位指定name属性的meas元素 return_values[0] = GetMeasValue(xml, "mt1"); return_values[1] = GetMeasValue(xml, "mt2"); return_values[2] = GetMeasValue(xml, "mt3"); return_values[3] = GetMeasValue(xml, "mt4"); return_values[4] = GetMeasValue(xml, "mt5"); // 输入XML中无此元素,返回空字符串 return_values[5] = GetMeasValue(xml, "mt6"); return return_values; } // 封装通用方法,避免重复代码 private string GetMeasValue(XmlDocument doc, string measName) { // XPath表达式:查找所有meas元素中name属性等于指定值的节点 XmlNode node = doc.SelectSingleNode($"//meas[@name='{measName}']"); return node?.InnerText ?? string.Empty; // 空节点时返回空字符串,避免异常 }
方法2:使用LINQ to XML(更简洁现代)
推荐使用XDocument(.NET 3.5+支持),语法更简洁,可读性更高:
using System.Xml.Linq; public string[] UnpackXML(string xml_string) { XDocument doc = XDocument.Parse(xml_string); var measNames = new[] { "mt1", "mt2", "mt3", "mt4", "mt5", "mt6" }; return measNames.Select(name => doc.Descendants("meas") .FirstOrDefault(m => m.Attribute("name")?.Value == name) ?.Value ?? string.Empty) .ToArray(); }
关键说明
- 两种方法都实现了直接通过name属性定位元素,无需遍历所有属性。
- 增加了空值判断(
?.和??),避免因XML中不存在指定name的元素(比如mt5)而触发空引用异常。 - LINQ to XML的方式代码更紧凑,适合处理此类场景。
内容的提问来源于stack exchange,提问作者bullfighter
相关产品推荐
相关产品推荐

