将子对象列表序列化为根级元素

时间:2019-05-13 16:23:48

标签: c# xml serialization

我正在尝试将包含List个孩子的父对象序列化为XML,该XML由一个父元素组成,每个子对象作为一个单独的元素。我想在子类型被序列化的任何时候都应用此方法,因此在子类型上实现IXmlSerializable似乎是理想的;但是,我还没有找到一个独立的解决方案。或者,是否可能向XmlAttributeOverrides提供XmlSerializer?我不介意在父级上添加属性,但想避免在父级上进行任何ISerializable实现(因为我有很多类型可以引用Child。)

示例类层次结构:

public class Parent {
    public string Name { get; set; }
    public string SomeProperty { get; set; }
// ....
    public List<Child> Children { get; set; }
}

public class Child { 
    public string Name { get; set; }
    public string Value { get; set; }
}

var o = new Parent {
   Name = "Test Parent",
   Children = new List<Child> {
      new Child { Name = "Alice", Value = "This is alice's value" },
      new Child { Name = "Bob", Value = "This is bob's value" }
   }
};

应序列化为:

<Parent>
  <Name>Test Parent</Name>
  <Alice>This is alice's value</Alice>
  <Bob>This is bob's value</Bob>
</Parent>

我在Child上创建了一个IXmlSerializable实现,如下:

public void WriteXml(XmlWriter writer) {     
   writer.WriteElementString(Name, Value.ToString());
}

并在[XmlElement]上添加了Children。 可以正确地序列化子级,但是它仍将嵌套在父级下太深的一级,例如:

<Parent>
  <Children>
    <Alice>this is alice</Alice>
 </Children>
</Parent>

希望我缺少一些技巧。谢谢!

1 个答案:

答案 0 :(得分:1)

the docs

  

您提供的WriteXml实现应写出对象的XML表示形式。 框架编写一个包装器元素,并在XML编写器启动后对其进行定位。您的实现可以编写其内容,包括子元素。 然后框架关闭包装元素。

因此,在序列化Parent时,框架将先写入Children,然后再写入多个Child元素,并在IXmlSerializable.WriteXml上调用您的Child实现,以便每个都写入< em>内容。

如果将[XmlElement]添加到Children,则它将写入多个Children元素(这是属性的名称),然后为每个子代调用实现。

鉴于其工作原理,除了在IXmlSerializable中实现Parent之外,我不确定您还有其他选择。