如何xml序列化 和反序列化类中包含的类

在 C# 中,对 包含嵌套类的类进行 XML 序列化和反序列化 是一个常见需求,尤其在处理复杂对象结构时。为了确保嵌套类能够被正确地序列化和反序列化,我们需要遵循一些基本规则,并使用适当的特性(Attributes)来控制序列化行为。


✅ 一、基本要求

在进行 XML 序列化时,以下几点是必须满足的:

条件 说明
无参数构造函数 所有参与序列化的类(包括嵌套类)都必须有无参数构造函数。
公共属性或字段 XML 序列化默认只处理 public 的属性或字段。
嵌套类也需要可序列化 嵌套类本身也必须满足上述条件,才能被正确序列化。

📌 二、XML 序列化嵌套类的示例

1. 定义包含嵌套类的类

csharp 复制代码
using System;
using System.Xml.Serialization;

[XmlRoot("Person")]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    // 嵌套类
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

2. 序列化为 XML 文件

csharp 复制代码
using System;
using System.IO;
using System.Xml.Serialization;

class Program
{
    static void Main()
    {
        Person person = new Person
        {
            Name = "Alice",
            Age = 25,
            Address = new Address
            {
                Street = "123 Main St",
                City = "New York"
            }
        };

        XmlSerializer serializer = new XmlSerializer(typeof(Person));
        using (StreamWriter writer = new StreamWriter("person.xml"))
        {
            serializer.Serialize(writer, person);
        }

        Console.WriteLine("对象已成功序列化为 XML 文件。");
    }
}

3. 反序列化 XML 文件为对象

csharp 复制代码
class Program
{
    static void Main()
    {
        string filePath = "person.xml";

        XmlSerializer serializer = new XmlSerializer(typeof(Person));
        using (StreamReader reader = new StreamReader(filePath))
        {
            Person person = (Person)serializer.Deserialize(reader);
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
            Console.WriteLine($"Address: {person.Address.Street}, {person.Address.City}");
        }
    }
}

🧩 三、处理集合类(如 List)

如果类中包含集合类(如 List<Address>),可以使用 [XmlArray] 和 [XmlArrayItem] 来控制集合的序列化格式。

示例结构

csharp 复制代码
[XmlRoot("Person")]
public class Person
{
    public string Name { get; set; }

    [XmlArray("Addresses")]
    [XmlArrayItem("Address")]
    public List<Address> Addresses { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

输出 XML 示例

xml 复制代码
<Person>
  <Name>Alice</Name>
  <Addresses>
    <Address>
      <Street>123 Main St</Street>
      <City>New York</City>
    </Address>
    <Address>
      <Street>456 Oak St</Street>
      <City>Los Angeles</City>
    </Address>
  </Addresses>
</Person>

⚠️ 四、常见问题与解决方案

问题 原因 解决方案
无法序列化嵌套类 嵌套类没有默认构造函数 添加无参数构造函数
字段未序列化 字段是 private 或未标记 使用 [XmlElement] 显式标记
集合类未序列化 没有使用 [XmlArray] 或 [XmlArrayItem] 添加集合序列化特性
序列化失败 类中包含接口或抽象类 使用 [XmlElement] 或自定义 XmlType
命名空间冲突 默认命名空间自动添加 使用 [XmlRoot(Namespace = "...")] 控制命名空间

📌 五、总结

步骤 操作
1 确保类和嵌套类都有无参数构造函数
2 使用 [XmlElement] 控制字段/属性的 XML 元素名称
3 使用 [XmlArray] 和 [XmlArrayItem] 控制集合类的序列化
4 使用 XmlSerializer.Serialize() 进行序列化
5 使用 XmlSerializer.Deserialize() 进行反序列化

通过上述方法,你可以轻松实现包含嵌套类或集合类的复杂对象的 XML 序列化和反序列化。只要确保嵌套类也满足序列化要求,就可以实现结构清晰、数据完整的 XML 文件读写。

相关推荐
死磕音视频10 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲12 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog12 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧13 小时前
C#:输入的字符串格式不正确
c#
程序喵大人14 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)14 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的15 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质15 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄62316 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_9628857216 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python