.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
相关产品推荐
相关产品推荐

