XmlSerializer序列化List时默认生成外层容器,需用XmlArray与XmlArrayItem特性配合包装类实现平级元素输出,或用XElement手动构建,或实现IXmlSerializable精细控制。

直接用 XmlSerializer 序列化 List 时,默认会生成一个外层容器元素(如 ),而你想要的是多个平级的 XML 元素(例如多个 ),不带外层包装。这需要自定义序列化行为,而不是依赖默认结构。
方法一:用 XmlArray 和 XmlArrayItem 指定元素名
这是最简洁、推荐的方式。通过特性告诉序列化器:把整个列表作为数组序列化,并为每个字符串指定子元素名,同时禁止生成默认的外层容器名。
做法是定义一个包装类,用 [XmlRoot] 去掉根名干扰,再用 [XmlArray] 和 [XmlArrayItem] 控制输出结构:
[XmlRoot("Items")]
public class StringListWrapper
{
[XmlArray(ElementName = "")]
[XmlArrayItem(ElementName = "Item")]
public List Items { get; set; } = new();
}
// 使用
var wrapper = new StringListWrapper { Items = new() { "a", "b", "c" } };
var serializer = new XmlSerializer(typeof(StringListWrapper));
using var writer = new StringWriter();
serializer.Serialize(writer, wrapper);
// 输出:
//
// - a
// - b
// - c
//
方法二:手动拼接 XML(适合简单场景)
如果只是临时导出、数据量小、且不需要严格遵循 XML 规范(如命名空间、转义等),可用 XElement 快速构建:
- 每个字符串创建一个
XElement,名称自定(如"Item") - 用
new XElement("Root", items.Select(s => new XElement("Item", s)))组合 - 调用
.ToString()或.Save()输出
注意:它会自动处理特殊字符(如 & → &),比字符串拼接安全。
方法三:实现 IXmlSerializable(完全自定义格式)
当需要精细控制每个节点的命名、属性、顺序,或混合不同类型时,可让类实现 IXmlSerializable。但对纯字符串列表来说略重,仅在以下情况考虑:
- 要求根元素为空(即直接输出多个
,不带任何外层标签) - 需为每个元素动态加属性(如
)- a
- 要兼容已有 XML Schema,且无法修改契约
此时需重写 WriteXml 方法,逐个写入 XmlWriter.WriteElementString,跳过 WriteStartDocument 和根节点。
避坑提醒
别直接序列化 ListXmlSerializer(typeof(List 一定会套上 ,且无法用特性覆盖;别忽略 XML 转义——手动字符串拼接遇到 " 会破坏结构,务必用 XElement 或 XmlWriter;空列表要测试——某些配置下可能不输出任何元素,需确认业务是否接受。









