You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}

关键说明

  1. 两种方法都实现了直接通过name属性定位元素,无需遍历所有属性。
  2. 增加了空值判断(?.和??),避免因XML中不存在指定name的元素(比如mt5)而触发空引用异常。
  3. LINQ to XML的方式代码更紧凑,适合处理此类场景。

内容的提问来源于stack exchange,提问作者bullfighter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:45:42