如何反序列化含xsi:type的异构XML数组?求最佳实现方案
处理带xsi:type的XML多态反序列化方案
针对服务XML结构变更(
1. 定义基类与派生类
创建一个基类作为
using System.Xml.Serialization; // 基类,标记支持的派生类型 [XmlInclude(typeof(Person))] [XmlInclude(typeof(Company))] // 替换为服务实际使用的ns0命名空间URL [XmlType(Namespace = "http://your-service-actual-namespace/ns0")] public class Entity { // 可选:添加Person和Company共有的属性,如Id等 } // 匹配xsi:type="ns0:person" [XmlType(TypeName = "person", Namespace = "http://your-service-actual-namespace/ns0")] public class Person : Entity { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } } // 匹配xsi:type="ns0:company" [XmlType(TypeName = "company", Namespace = "http://your-service-actual-namespace/ns0")] public class Company : Entity { public string CompanyName { get; set; } public string Address { get; set; } public int EmployeeCount { get; set; } }
2. 调整Response与Data类结构
将Data类中的Item集合改为基类Entity的列表,让XmlSerializer自动根据xsi:type识别具体类型:
[XmlRoot("Response")] public class Response { public Data Data { get; set; } } public class Data { // 用XmlElement标记,对应XML中的<item>节点 [XmlElement("item")] public List<Entity> Items { get; set; } }
3. 执行反序列化
使用XmlSerializer标准流程完成反序列化,无需额外复杂配置:
using System.IO; using System.Xml.Serialization; public static Response DeserializeServiceResponse(string xmlContent) { var serializer = new XmlSerializer(typeof(Response)); using (var stringReader = new StringReader(xmlContent)) { return (Response)serializer.Deserialize(stringReader); } }
关键注意事项
- 命名空间必须完全匹配:XML中
xmlns:ns0="xxx"的xxx值,要和类特性中的Namespace参数完全一致,否则无法识别xsi:type。 - XmlInclude不可省略:必须在基类上添加
[XmlInclude]标记所有派生类型,告诉XmlSerializer这些类型的存在。 - 类型名称要对应:xsi:type中的"person"/"company",要和派生类
[XmlType(TypeName = "...")]的参数完全一致(区分大小写)。
类型判断与使用
反序列化后,可通过模式匹配或类型转换获取具体对象:
var response = DeserializeServiceResponse(xmlContent); foreach (var item in response.Data.Items) { if (item is Person person) { // 处理Person对象 Console.WriteLine($"Person: {person.FirstName} {person.LastName}"); } else if (item is Company company) { // 处理Company对象 Console.WriteLine($"Company: {company.CompanyName}"); } }
内容的提问来源于stack exchange,提问作者Yesimzhan Makishev
相关产品推荐
相关产品推荐

