C# 解析xml时常见的异常及处理方法

来源:这里教程网 时间:2026-02-21 17:28:46 作者:

在使用 C# 解析 XML 时,虽然 System.Xml 提供了强大的支持,但在实际开发中经常会遇到各种异常。了解这些常见异常及其处理方式,有助于提升程序的健壮性和可维护性。

1. XmlException:XML 格式不合法

原因:这是最常见的异常,通常由格式错误引起,例如标签未闭合、属性值缺少引号、非法字符等。

示例场景

XML 字符串为 (name 属性没加引号)

处理方法

使用 try-catch 捕获 XmlException,并记录原始 XML 内容以便排查。 验证输入源是否完整,尤其是从网络或文件读取时。 对用户提交的 XML 增加预校验逻辑,或使用工具如 XmlReader 配合 ConformanceLevel.Fragment 处理片段。

代码示例

try {
    var doc = new XmlDocument();
    doc.LoadXml(xmlString);
} catch (XmlException ex) {
    // 记录错误位置 LineNumber 和 LinePosition
    Console.WriteLine($"XML 格式错误:{ex.Message}, 行:{ex.LineNumber}, 位置:{ex.LinePosition}");
}

2. FileNotFoundException 或 DirectoryNotFoundException:文件路径问题

原因:尝试加载一个不存在的 XML 文件,或路径拼写错误、权限不足。

处理方法

在调用 Load 或 LoadXml 前检查文件是否存在:File.Exists(filePath) 使用绝对路径或确保相对路径正确(特别是部署后的工作目录变化)。 捕获 IOException 及其子类,统一处理文件访问异常。

建议:优先使用 XmlReader 加载大文件,避免一次性全部读入内存。

3. NullReferenceException:节点或属性为空

原因:未判断节点是否存在就直接访问 InnerText、Attributes 等成员。

示例场景

var value = node["child"].InnerText; // 若 child 节点不存在,则 node["child"] 为 null

处理方法

访问子节点前先判断是否为 null:if (node != null) 使用条件访问运算符 ?.(C# 6+):node?["child"]?.InnerText 用 SelectSingleNode 查询时,始终检查返回值是否为 null。

推荐做法:封装安全取值方法,如:

public static string GetElementValue(XmlNode node, string xpath) {
    var n = node.SelectSingleNode(xpath);
    return n?.InnerText ?? string.Empty;
}

4. InvalidOperationException:操作不被允许

原因:可能出现在使用 XmlReader 时未正确调用 Read(),或在只读模式下尝试修改节点。

常见情况

调用 XmlReader 的 ReadElementContentAsString() 前未定位到元素。 在遍历 XmlNodeList 时尝试修改集合(如删除节点),引发枚举器失效。

处理方法

确保 XmlReader 正确推进,使用 Read() 判断是否有数据。 需要修改节点集合时,先缓存目标节点到数组或列表中再操作。

5. OutOfMemoryException:解析过大 XML 文件

原因:使用 XmlDocument 将整个 XML 加载进内存,导致内存溢出。

处理方法

改用 XmlReader 进行流式读取,逐节点处理,降低内存占用。 对于大型配置文件,考虑分块处理或使用 XPath 过滤关键节点。

示例:用 XmlReader 读取大数据集:

using var reader = XmlReader.Create("big.xml");
while (reader.Read()) {
    if (reader.NodeType == XmlNodeType.Element && reader.Name == "Record") {
        // 处理单条记录
    }
}

基本上就这些。合理选择解析方式、做好异常捕获和空值判断,能有效避免大多数 XML 相关问题。关键是根据场景选对工具:小文件用 XmlDocument,大文件用 XmlReader。不复杂但容易忽略细节。

相关推荐