Search code examples
c#serializationxml-serialization

C# Serialization hide array name of list containing sub classes


My goal is to output XML like the sample below:

<FunctionList name="list1">
 <Space title="RoomA">
  <Space title="Cabinet1">
   <Device title="Device1"/>
   <Device title="Device2"/>
  </Space>
  <Space title="Cabinet2">
   <Device title="Device3"/>
  </Space>
 </Space>
</Locations>

However the Serializer outputs the variable that contains the child elements.

<FunctionList name="list1">
 **<elements>**
  <Space title="RoomA">
   **<Children>**
    <Space title="Cabinet1">
     **<Children>**
      <Device title="Device1"/>
      <Device title="Device2"/>
     **</Children>**
    </Space>
    <Space title="Cabinet2">
     **<Children>**
      <Device title="Device3"/>
     **</Children>**
    </Space>
   **</Children>**
  </Space>
 **</elements>**
</Locations>

I would like to get rid of the bold xml elements, because they expose C# variables where it is obvious from the XML structure that it is a parent-child relation. However maybe this is wrong logic from my side.

XML tag and Class Space and Device are subclasses of DesignElement.

[Serializable]
public class FunctionList
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlArray("Element")]
    [XmlArrayItem(nameof(Space), typeof(Space))]
    [XmlArrayItem(nameof(Device), typeof(Device))]
    public List<DesignElement> elements { get; set; }
}

[Serializable]
public abstract class DesignElement
{
    [XmlAttribute("title")]
    public string Title { get; set; }
}

[Serializable]
public class Space : DesignElement
{
    [XmlArray("Children")]
    [XmlArrayItem(nameof(Space), typeof(Space))]
    [XmlArrayItem(nameof(Device), typeof(Device))]
    public List<DesignElement> children {  get; set; }
}

[Serializable]
public class Device: DesignElement
{

}

I tried multiple things with [XmlArray("Children")] and [XmlArray("Element")]. I think the solution is somewhat like [XmlElement(typeof(object))] but I cannot find the right syntax. But perhaps I have the wrong angle to this problem.


Solution

  • untested, but I believe you want:

    [XmlElement(nameof(Space), typeof(Space))]
    [XmlElement(nameof(Device), typeof(Device))]
    public List<DesignElement> children {  get; set; } // or elements