C# XML序列化:如何将0..1次出现的子元素属性映射为类属性?
解决方案
要实现将Root类的TestEnum属性序列化为你给出的XML结构(<root><Element testType="tst1"/></root>),直接在TestEnum属性上添加单一特性是做不到的——因为.NET的XmlSerializer没有提供直接将类属性映射到子元素的属性的特性。不过有两种常用的实现方式,我给你详细说明:
方案一:创建嵌套类表示<Element>元素
这是最直观的方式,通过一个小类来封装<Element>元素及其testType属性:
public class Root { // XmlElement指定子元素名为"Element",IsNullable=true允许元素不出现(对应0..1次) [XmlElement("Element", IsNullable = true)] public Element Element { get; set; } } // 专门表示<Element>元素的类 public class Element { // XmlAttribute将属性映射为元素的testType属性 [XmlAttribute("testType")] public TestEnum TestType { get; set; } } public enum TestEnum { [XmlEnum("tst1")] Test1, [XmlEnum("tst2")] Test2 }
当Element属性为null时,序列化后的XML不会包含<Element>元素;如果设置了IsNullable=true,会生成<Element xsi:nil="true"/>,你可以根据需求选择是否保留这个参数。
方案二:使用代理属性避免额外类
如果你不想单独创建Element类,可以用代理属性结合XmlIgnore特性来实现,把实际业务属性隐藏,用代理属性处理序列化逻辑:
public class Root { // XmlIgnore告诉序列化器跳过这个属性 [XmlIgnore] public TestEnum TestEnum { get; set; } // 代理属性,对应XML中的<Element>元素 [XmlElement("Element")] public ElementProxy ElementWrapper { get { return new ElementProxy { TestType = this.TestEnum }; } set { if (value != null) { this.TestEnum = value.TestType; } } } // 仅用于序列化的内部代理类 private class ElementProxy { [XmlAttribute("testType")] public TestEnum TestType { get; set; } } } public enum TestEnum { [XmlEnum("tst1")] Test1, [XmlEnum("tst2")] Test2 }
这种方式让你可以直接操作Root类的TestEnum属性,同时序列化出你想要的XML结构。
额外说明
如果你其实是希望TestEnum对应<Element>元素的文本内容(比如<Element>tst1</Element>),那只需要给TestEnum属性添加[XmlElement("Element")]特性即可,这是最简单的情况:
public class Root { [XmlElement("Element")] public TestEnum TestEnum { get; set; } }
内容的提问来源于stack exchange,提问作者Marius M
相关产品推荐
相关产品推荐

