如何将C#嵌套类对象序列化为无嵌套的扁平结构XML
C# 嵌套类扁平序列化XML实现方案
结论
完全可以实现,基于.NET自带的System.Xml.Serialization库就可以完成,不需要引入第三方组件,以下是两种适用不同场景的实现方式:
方案1:代理属性实现(适合ClassB结构固定、字段少的场景)
通过[XmlIgnore]标记忽略嵌套的ClassB节点,直接在ClassA中暴露ClassB属性的代理访问器,走默认序列化逻辑即可输出扁平结构:
using System.Xml.Serialization; public class ClassA { public string Identifier { get; set; } // 忽略嵌套序列化 [XmlIgnore] public ClassB ClassBItem { get; set; } // 代理ClassB的属性,序列化时直接作为ClassA的子节点 public string Name { get => ClassBItem?.Name; set => ClassBItem.Name = value; } public string Description { get => ClassBItem?.Description; set => ClassBItem.Description = value; } } public class ClassB { public string Name { get; set; } public string Description { get; set; } }
方案2:实现IXmlSerializable接口(适合ClassB结构复杂、字段多的场景)
如果ClassB字段较多或者后续会迭代调整,手动加代理属性维护成本高,可以通过自定义序列化逻辑完全控制XML输出:
using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; public class ClassA : IXmlSerializable { public string Identifier { get; set; } public ClassB ClassBItem { get; set; } public XmlSchema GetSchema() => null; // 不需要反序列化可以空实现此方法 public void ReadXml(XmlReader reader) { reader.ReadStartElement(nameof(ClassA)); Identifier = reader.ReadElementContentAsString(nameof(Identifier), string.Empty); ClassBItem = new ClassB { Name = reader.ReadElementContentAsString(nameof(ClassB.Name), string.Empty), Description = reader.ReadElementContentAsString(nameof(ClassB.Description), string.Empty) }; reader.ReadEndElement(); } // 自定义序列化输出扁平节点 public void WriteXml(XmlWriter writer) { writer.WriteElementString(nameof(Identifier), Identifier); writer.WriteElementString(nameof(ClassB.Name), ClassBItem.Name); writer.WriteElementString(nameof(ClassB.Description), ClassBItem.Description); } } public class ClassB { public string Name { get; set; } public string Description { get; set; } }
测试序列化代码
var testObj = new ClassA { Identifier = "Some identifier", ClassBItem = new ClassB { Name = "Some name", Description = "Some description" } }; // 去掉默认的命名空间声明,输出和需求完全一致的XML var ns = new XmlSerializerNamespaces(); ns.Add("", ""); var serializer = new XmlSerializer(typeof(ClassA)); using var sw = new StringWriter(); serializer.Serialize(sw, testObj, ns); // 输出结果即为你需要的扁平XML结构 Console.WriteLine(sw.ToString());
你已经保证所有节点名称无重复,两种方案都不会出现节点冲突问题。
内容的提问来源于stack exchange,提问作者Rector
相关产品推荐
相关产品推荐

