Search code examples
c#xmlxml-serialization

c# XML serialization - dynamic element name


My current XML structure is:

<Parent>
 <Child>
   <Line id="1">Something</Line>
   <Line id="2">Something</Line>
 </Child>
 <Child>
   <Line id="1">Something else</Line>
   <Line id="2">Something else</Line>
 </Child>
</Parent>

Parent class code contains property:

[XmlElement("Child")]
public List<Child> Childrens { get; set; }

Now I want this to be changed to:

<Parent>
 <Child>
   <Line id="1">Something</Line>
   <Line id="2">Something</Line>
 </Child>
 <SpecialChild>
   <Line id="1">Some other text</Line>
   <Line id="2">Some other text</Line>
 </SpecialChild>
</Parent>

I.e. when Child has some special flag set, it's name should be changed, and some other text be printed. Child already knows what text to print depending on flag.

But what will be the best option to change element name now?


Solution

  • I think you should be able to use inheritance for this:

    [XmlElement("Child", typeof(Child))]
    [XmlElement("SpecialChild", typeof(SpecialChild))]
    public List<Child> Childrens { get; set; }
    

    with

    public class SpecialChild : Child {...}
    

    However: without inheritance, it isn't natively supported and you'd need to perform manual serialization.


    Edit: confirmed, works fine:

    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    class Program
    {    static void Main()
        {
            var ser = new XmlSerializer(typeof(Parent));
            var obj = new Parent
            {
                Childrens = {
                    new Child { },
                    new SpecialChild { },
                }
            };
            ser.Serialize(Console.Out, obj);
        }
    }
    public class Parent
    {
        [XmlElement("Child", typeof(Child))]
        [XmlElement("SpecialChild", typeof(SpecialChild))]
        public List<Child> Childrens { get; } = new List<Child>();
    }
    public class Child { }
    public class SpecialChild : Child { }