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

.Net XmlSerializer:宽松模式解析XML,遇错误时继续反序列化

XmlSerializer处理含非法值XML的反序列化行为

默认情况下,XmlSerializer采用严格解析策略:只要XML中有一个属性值无法正确解析(比如格式错误的日期、类型不匹配的数值等),整个反序列化过程会直接抛出InvalidOperationException并终止,无法获取任何已解析完成的属性数据。

如果需要在部分属性解析出错时继续完成反序列化,必须通过自定义解析逻辑实现:

  • 实现IXmlSerializable接口:手动编写反序列化的节点读取逻辑,对每个字段单独处理。遇到非法值时,可以选择跳过该字段、设置默认值或标记为无效,而不中断整个解析流程。
  • 使用XmlReader逐节点读取:直接通过XmlReader遍历XML节点,自行控制解析顺序和错误处理,捕获单个节点的解析异常后继续处理后续节点。

举个简单的实现示例(以处理非法日期为例):

定义实体类并实现IXmlSerializable:

public class MyData : IXmlSerializable
{
    public int Id { get; set; }
    public DateTime? ValidDate { get; set; }
    public string Name { get; set; }

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement();
        while (reader.NodeType != XmlNodeType.EndElement)
        {
            switch (reader.LocalName)
            {
                case "Id":
                    Id = int.Parse(reader.ReadElementContentAsString());
                    break;
                case "ValidDate":
                    var dateStr = reader.ReadElementContentAsString();
                    if (DateTime.TryParse(dateStr, out var validDate))
                    {
                        ValidDate = validDate;
                    }
                    else
                    {
                        ValidDate = null; // 非法日期设为null,不中断解析
                    }
                    break;
                case "Name":
                    Name = reader.ReadElementContentAsString();
                    break;
                default:
                    reader.Skip(); // 跳过未知节点
                    break;
            }
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Id", Id.ToString());
        if (ValidDate.HasValue)
        {
            writer.WriteElementString("ValidDate", ValidDate.Value.ToString("yyyy-MM-dd"));
        }
        writer.WriteElementString("Name", Name ?? string.Empty);
    }
}

通过这种方式,即使ValidDate字段值非法,Id和Name依然能正常解析,反序列化过程不会中断。

内容的提问来源于stack exchange,提问作者s.demuro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:58:16