Search code examples
c#xmlxml-serialization

How to achieve the required XML serialisation?


The following class:

    public class CodelistFilters
    {
        [System.Xml.Serialization.XmlArray]
        public List<CodelistFilterAndElement> AndGroup;

    }
    public class CodelistFilterAndElement
    {
        [System.Xml.Serialization.XmlArray]
        public List<CodelistFilterOrElement> OrGroup;

        [System.Xml.Serialization.XmlAttribute]
        public string Relationship { get { return "And"; } }
    }

    public class CodelistFilterOrElement
    {
        [System.Xml.Serialization.XmlElement]
        public List<CodelistFilter> CodelistFilters;

        [System.Xml.Serialization.XmlAttribute]
        public string Relationship { get { return "Or"; } }
    }

    public class CodelistFilter
    {
        [System.Xml.Serialization.XmlAttribute]
        public string Name { get; set; }

        [System.Xml.Serialization.XmlAttribute]
        public string Value1 { get; set; }

        [System.Xml.Serialization.XmlAttribute]
        public string Value2 { get; set; }

    }

gets serialised as

<CodelistFilters xmlns:xsi="http://www.w3.org/2001/XMLSchema">
<AndGroup>
    <CodelistFilterAndElement>
        <OrGroup>
            <CodelistFilterOrElement>
                <CodelistFilters>
                    <CodelistFilter Name="Description" Value1="test" />
                </CodelistFilters>
            </CodelistFilterOrElement>
        </OrGroup>
    </CodelistFilterAndElement>
</AndGroup>

Which I sort of understand. However, what I'm trying to achieve this:

<CodelistFilters xmlns:xsi="http://www.w3.org/2001/XMLSchema">
<Group Relationship="And"> 
    <Group Relationship="Or">
        <CodelistFilters Name="Description" Value1="test" />
    </Group>
</Group>

How should I structure my C# class to achieve this? I've tried messing around with XmlAttributes and nested Lists but just end up with different versions of "wrong".


Solution

  • As hinted in the comments, you need to have a 1:1 mapping between your XML and your classes. You only have 3 elements in your required XML, so you need 3 classes to represent these.

    public class CodelistFilters
    {    
        [XmlElement("Group")]
        public List<Group> Groups { get; set; }
    }
    
    public class Group
    {
        [XmlAttribute]
        public string Relationship { get; set; }
    
        [XmlElement("Group")]
        public List<Group> Groups { get; set; }
    
        [XmlElement("CodelistFilter")]
        public List<CodelistFilter> CodelistFilters { get; set; }
    }
    
    public class CodelistFilter
    {
        [XmlAttribute]
        public string Name { get; set; }
    
        [XmlAttribute]
        public string Value1 { get; set; }
    
        [XmlAttribute]
        public string Value2 { get; set; }
    }
    

    See this fiddle for a working demo.