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

如何反序列化含xsi:type的异构XML数组?求最佳实现方案

处理带xsi:type的XML多态反序列化方案

针对服务XML结构变更(通过xsi:type标记为ns0:person/ns0:company),可以通过C# XmlSerializer的多态序列化支持完成反序列化,核心是利用基类+XmlIncludeAttribute配置配合命名空间匹配,具体实现步骤如下:

1. 定义基类与派生类

创建一个基类作为的通用类型,让Person和Company继承它,同时通过特性指定命名空间和类型名称,确保和服务返回的xsi:type匹配:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:05:24