XmlSerializer无法直接序列化List,因Dictionary无无参构造函数且非标准可序列化集合;推荐两种方案:方法一用XmlDocument手动构建XML(灵活可控,适合动态结构),方法二转为强类型中间类后序列化(类型安全,适合固定字段)。

用 XmlSerializer 不能直接序列化 List,因为 Dictionary 不支持 XML 序列化(它没有无参构造函数,且不是可枚举的“标准”集合类型)。但有几种实用、可控的方式可以转换,下面介绍最常用且清晰的两种方法。
方法一:手动构建 XmlDocument(推荐,灵活可控)
适合字段名、结构已知或需自定义 XML 标签名/层级的情况。核心是遍历列表和字典,逐个创建节点。
- 创建空的
XmlDocument - 添加根节点(如
) - 对每个
Dictionary创建一个子元素(如) - 对每组
Key-Value,生成对应子节点(),自动处理字符串转义Value - 值为
null或非基础类型时建议跳过或转成空字符串,避免异常
示例片段:
var doc = new XmlDocument();
var root = doc.CreateElement("Items");
doc.AppendChild(root);
foreach (var dict in list)
{
var itemNode = doc.CreateElement("Item");
foreach (var kvp in dict)
{
if (kvp.Key == null) continue;
var keyNode = doc.CreateElement(kvp.Key.ToString());
var value = kvp.Value?.ToString() ?? "";
keyNode.InnerText = value;
itemNode.AppendChild(keyNode);
}
root.AppendChild(itemNode);
}
string xml = doc.OuterXml;
方法二:先转成可序列化的中间类(类型安全,适合固定结构)
如果你的字典其实代表统一的数据结构(比如都是 "Name", "Age", "City"),定义一个简单类更清晰、可验证、易维护。
- 新建一个类(如
Person),属性与字典 Key 一一对应 - 用 LINQ 把
List映射成> List - 用
XmlSerializer直接序列化该列表 - 优点:XML 结构明确、支持特性控制(如
[XmlElement])、可反序列化回来
示例:
// 定义类public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
// 转换 + 序列化
var persons = list.Select(d => new Person
{
Name = d.GetValueOrDefault("Name")?.ToString(),
Age = Convert.ToInt32(d.GetValueOrDefault("Age") ?? "0"),
City = d.GetValueOrDefault("City")?.ToString()
}).ToList();
var serializer = new XmlSerializer(typeof(List));
using var writer = new StringWriter();
serializer.Serialize(writer, persons);
string xml = writer.ToString();
小提醒:避免踩坑
不要尝试直接序列化 Dictionary —— 会抛 InvalidOperationException;
XML 标签名不能含空格、特殊字符或以数字开头 —— 建议清洗 key(如替换空格为下划线);
如果 value 是嵌套对象或集合,上面两种方法默认只取 .ToString(),需额外递归处理(这时建议用 JSON 中转或选第三方库如 ServiceStack.Text);
中文等 Unicode 内容无需额外处理,XmlDocument 和 XmlSerializer 默认支持 UTF-8。
基本上就这些。按你的数据是否结构固定来选:动态任意键用方法一,业务模型明确用方法二。不复杂但容易忽略 key 合法性和 null 处理。









