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

如何反序列化XML标签列表并保留类继承结构?

XML反序列化保留子类属性值

给定的XML结构:

<Root>
    <People>
        <Person>
            <Name>John</Name>
        </Person>
        <Customer>
            <Name>Johnny</Name>
            <Money>400</Money>
        </Customer>
        <Student>
            <Name>Johnson</Name>
            <GPA>2.5</GPA>
        </Student>
    </People>
</Root>

对应的C#类结构(原版本):

public class Person
{
    public string Name;
}
public class Customer : Person
{
    public int Money;
}
public class Student : Person
{
    public float GPA;
}
public class Root
{
    public List<Person> People;
}

要实现正确反序列化并保留子类属性,需要给类添加正确的XML序列化特性:

修改后的C#类

using System.Xml.Serialization;
using System.Collections.Generic;

[XmlInclude(typeof(Customer))]
[XmlInclude(typeof(Student))]
public class Person
{
    public string Name;
}

public class Customer : Person
{
    public int Money;
}

public class Student : Person
{
    public float GPA;
}

public class Root
{
    [XmlElement("Person", typeof(Person))]
    [XmlElement("Customer", typeof(Customer))]
    [XmlElement("Student", typeof(Student))]
    public List<Person> People;
}

反序列化代码示例

using System.IO;
using System.Xml.Serialization;

// 读取XML文件内容
var xmlContent = File.ReadAllText("your-xml-file-path.xml");

// 创建XmlSerializer实例
var serializer = new XmlSerializer(typeof(Root));

// 执行反序列化
using var reader = new StringReader(xmlContent);
var root = (Root)serializer.Deserialize(reader);

// 验证结果:遍历People列表,检查子类属性
foreach (var person in root.People)
{
    if (person is Customer customer)
    {
        Console.WriteLine($"Customer: {customer.Name}, Money: {customer.Money}");
    }
    else if (person is Student student)
    {
        Console.WriteLine($"Student: {student.Name}, GPA: {student.GPA}");
    }
    else
    {
        Console.WriteLine($"Person: {person.Name}");
    }
}

关键说明

  1. XmlInclude特性:在基类Person上添加该特性,告诉XmlSerializer需要处理哪些子类类型,避免序列化/反序列化时类型识别失败。
  2. XmlElement特性:在Root的People属性上配置多个XmlElement,每个元素对应XML中的节点名称和对应的子类类型。这样XmlSerializer会根据XML里的节点名(Person/Customer/Student)自动实例化对应的子类,并填充所有属性值。

你之前尝试失败的原因大概率是没在People属性上正确配置XmlElement映射,导致XmlSerializer只把所有节点都解析成基类Person实例,自然无法保留子类的Money和GPA属性。

内容的提问来源于stack exchange,提问作者Yormi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:20:26