C#不支持xml直接反序列化为dynamic,但可通过XDocument递归构建ExpandoObject实现;也可用DynamicXml等第三方库简化操作,适用于配置读取等场景。

C#本身不支持直接将XML反序列化为dynamic对象(如ExpandoObject),因为XmlSerializer要求编译时已知类型,而dynamic是运行时绑定的。但可以通过组合XDocument解析 + 递归构建ExpandoObject来实现等效效果。
使用XDocument手动构建ExpandoObject
这是最常用、可控性最强的方式:先用XDocument.Load()或XDocument.Parse()加载XML,再递归遍历节点,把元素和属性转为ExpandoObject的属性。
- 元素名作为属性名,文本内容作为值(若无子元素)
- 同名多个子元素转为
List - 属性(
XAttribute)可存入特殊字典字段(如@attrName)或单独对象 - 需注意类型推断——XML文本默认是字符串,如需数字/布尔,需自行尝试转换(
int.TryParse等)
封装一个通用的XmlToDynamic方法
以下是一个简洁可用的辅助方法(支持嵌套、数组、属性):
public static dynamic XmlToDynamic(string xml) { var doc = XDocument.Parse(xml); return ToExpando(doc.Root); } private static dynamic ToExpando(XElement element) { var expando = new ExpandoObject() as IDictionary; // 添加属性(前缀@) foreach (var attr in element.Attributes()) expando[$"@{attr.Name}"] = attr.Value; // 处理子元素 var elements = element.Elements().ToArray(); var grouped = elements.GroupBy(e => e.Name).ToList(); foreach (var g in grouped) { var value = g.Count() == 1 ? ToExpandoOrValue(g.First()) : g.Select(ToExpandoOrValue).Cast
使用第三方库(如DynamicXml)
社区有轻量封装库简化该流程,例如DynamicXml:
- NuGet安装:
Install-Package DynamicXml - 用法简单:
dynamic xml = new DynamicXml(xmlString); - 支持点语法访问:
xml.Book.Title、xml.Book.Author[0].Name - 内部仍基于
XDocument,但屏蔽了构建细节,适合快速原型
注意事项与限制
这类方案不是真正的“反序列化”,而是运行时结构映射,需注意:
- 无法享受
XmlSerializer的命名空间、CDATA、注释等高级特性支持 - 性能不如强类型反序列化(尤其大数据量),但对配置类小XML足够快
-
dynamic丢失编译期检查,建议仅用于脚本化、配置读取或临时数据处理场景 - 若需双向(dynamic → XML),需额外实现
ToXml()逻辑