Deserialization of xml file by using XmlArray?

20,441

You need a common type to be able to deserialize your XML, and with that you can define with the [XmlElement] namespace what type to instantiate depending on the name of the element, as shown below.

public class StackOverflow_15907357
{
    const string XML = @"<?xml version=""1.0""?>
                        <DietPlan>
                            <Health>
                                <Fruit>Test</Fruit>
                                <Fruit>Test</Fruit>
                                <Veggie>Test</Veggie>
                                <Veggie>Test</Veggie>
                            </Health>
                        </DietPlan>";

    [XmlRoot(ElementName = "DietPlan")]
    public class TestSerialization
    {
        [XmlArray("Health")]
        [XmlArrayItem("Fruit", Type = typeof(Fruit))]
        [XmlArrayItem("Veggie", Type = typeof(Veggie))]
        public Food[] Foods { get; set; }
    }

    [XmlInclude(typeof(Fruit))]
    [XmlInclude(typeof(Veggie))]
    public class Food
    {
        [XmlText]
        public string Text { get; set; }
    }

    public class Fruit : Food { }
    public class Veggie : Food { }

    public static void Test()
    {
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
        XmlSerializer xs = new XmlSerializer(typeof(TestSerialization));
        TestSerialization obj = (TestSerialization)xs.Deserialize(ms);
        foreach (var food in obj.Foods)
        {
            Console.WriteLine("{0}: {1}", food.GetType().Name, food.Text);
        }
    }
}
Share:
20,441
now he who must not be named.
Author by

now he who must not be named.

#SOreadytohelp There is this joy in helping others. Thanks SO

Updated on April 10, 2020

Comments

  • now he who must not be named.
    now he who must not be named. about 4 years

    I am trying to deserialize this xml structure.

    <?xml version="1.0"?>
    <DietPlan>
        <Health>
            <Fruit>Test</Fruit>
            <Fruit>Test</Fruit>
            <Veggie>Test</Veggie>
            <Veggie>Test</Veggie>
        </Health>
    </DietPlan>
    

    And I tried:

    [Serializable]
    [XmlRoot(ElementName = "DietPlan")]
    public class TestSerialization
    {
        [XmlArray("Health")]
        [XmlArrayItem("Fruit")]
        public string[] Fruits { get; set; }
    
        [XmlArray("Health")]
        [XmlArrayItem("Veggie")]
        public string[] Veggie { get; set; }
    }
    

    But this throws an exception "The XML element is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element." Thanks in adv.