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

.NET中使用XmlSerializer序列化基类列表为指定XML结构可行吗?

用XmlSerializer实现指定分组结构的Action子类列表XML序列化

可以实现,XmlSerializer完全支持处理继承关系的对象序列化,结合特性配置就能生成你需要的分组结构XML,具体步骤如下:

1. 标记继承关系

首先要在基类Action上通过[XmlInclude]特性声明所有需要序列化的子类,让XmlSerializer知晓这些类型的存在,避免序列化时抛出类型未知的异常:

[XmlInclude(typeof(AddCircle))]
[XmlInclude(typeof(DeleteCircle))]
[XmlInclude(typeof(AddTriangle))]
[XmlInclude(typeof(DeleteTriangle))]
public abstract class Action
{
    public string Id { get; set; }
}

// 子类定义,可通过[XmlType]指定XML元素名
[XmlType("AddCircle")]
public class AddCircle : Action
{
    public int Radius { get; set; }
}

[XmlType("DeleteCircle")]
public class DeleteCircle : Action
{
    public string CircleId { get; set; }
}

[XmlType("AddTriangle")]
public class AddTriangle : Action
{
    public int SideLength { get; set; }
}

[XmlType("DeleteTriangle")]
public class DeleteTriangle : Action
{
    public string TriangleId { get; set; }
}

2. 定义分组包装类

如果需要按特定规则(比如操作类型、形状类型)分组,要创建一个包装类,通过[XmlArray]指定分组的根节点名,再用[XmlArrayItem]绑定对应的子类和XML元素名:

示例1:按操作类型(Add/Delete)分组

[XmlRoot("ActionList")]
public class ActionTypeGroupWrapper
{
    [XmlArray("AddOperations")]
    [XmlArrayItem(typeof(AddCircle), ElementName = "AddCircle")]
    [XmlArrayItem(typeof(AddTriangle), ElementName = "AddTriangle")]
    public List<Action> AddActions { get; set; } = new List<Action>();

    [XmlArray("DeleteOperations")]
    [XmlArrayItem(typeof(DeleteCircle), ElementName = "DeleteCircle")]
    [XmlArrayItem(typeof(DeleteTriangle), ElementName = "DeleteTriangle")]
    public List<Action> DeleteActions { get; set; } = new List<Action>();
}

示例2:按形状类型(Circle/Triangle)分组

[XmlRoot("ActionList")]
public class ShapeTypeGroupWrapper
{
    [XmlArray("CircleActions")]
    [XmlArrayItem(typeof(AddCircle), ElementName = "AddCircle")]
    [XmlArrayItem(typeof(DeleteCircle), ElementName = "DeleteCircle")]
    public List<Action> CircleActions { get; set; } = new List<Action>();

    [XmlArray("TriangleActions")]
    [XmlArrayItem(typeof(AddTriangle), ElementName = "AddTriangle")]
    [XmlArrayItem(typeof(DeleteTriangle), ElementName = "DeleteTriangle")]
    public List<Action> TriangleActions { get; set; } = new List<Action>();
}

3. 执行序列化

将原始的List<Action>按分组规则拆分后放入包装类,再进行序列化:

// 构造测试数据
var allActions = new List<Action>
{
    new AddCircle { Id = "A1", Radius = 10 },
    new DeleteCircle { Id = "D1", CircleId = "Circle_001" },
    new AddTriangle { Id = "A2", SideLength = 6 },
    new DeleteTriangle { Id = "D2", TriangleId = "Triangle_001" }
};

// 按操作类型分组
var groupWrapper = new ActionTypeGroupWrapper
{
    AddActions = allActions.Where(a => a is AddCircle || a is AddTriangle).ToList(),
    DeleteActions = allActions.Where(a => a is DeleteCircle || a is DeleteTriangle).ToList()
};

// 序列化
var serializer = new XmlSerializer(typeof(ActionTypeGroupWrapper));
using var stringWriter = new StringWriter();
serializer.Serialize(stringWriter, groupWrapper);
string resultXml = stringWriter.ToString();

生成的XML结构大概如下:

<ActionList>
  <AddOperations>
    <AddCircle>
      <Id>A1</Id>
      <Radius>10</Radius>
    </AddCircle>
    <AddTriangle>
      <Id>A2</Id>
      <SideLength>6</SideLength>
    </AddTriangle>
  </AddOperations>
  <DeleteOperations>
    <DeleteCircle>
      <Id>D1</Id>
      <CircleId>Circle_001</CircleId>
    </DeleteCircle>
    <DeleteTriangle>
      <Id>D2</Id>
      <TriangleId>Triangle_001</TriangleId>
    </DeleteTriangle>
  </DeleteOperations>
</ActionList>

注意事项

  • 必须显式声明所有需要序列化的子类,无论是通过基类的[XmlInclude],还是在创建XmlSerializer实例时传入类型数组。
  • 如果不需要分组,直接序列化List<Action>也可以,但生成的XML是无分组的平级列表,所有子类元素会直接放在根节点下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:42:37