Search code examples
c#deserialization

How to deserialize child object into list of parent (ex, List<Parent>) based on values of xml nodes?


I have one XML file called VehicleInfo. I want to deserialize VehicleInfo in List of Vehicle. Now I have one base class called Vehicle and three derived class named as Car, Bike, Truck. How to deserialize specific object of vehicle based on value of Vehicle node in xml. (ex. if node value is Car than object of car should be stored in List of vehicle)

<Vehicles>
    <Vehicle>Car</Vehicle>
    <Vehicle>Bike</Vehicle>
    <Vehicle>Truck</Vehicle>
</Vehicles>

For example,

VehicleList class :

public class VehicleList
{
    List<Vehicle> lstVehicles = new List<Vehicle>();
}

Vehicle class :

public class Vehicle
{
    public string name = "Vehicle";
}

Car class :

public class Car : Vehicle
{
    public Car()
    {
        name = "Car";
    }
}

Bike class :

public class Bike : Vehicle
{
    public Bike()
    {
        name = "Bike";
    }
}

Truck class :

public class Truck : Vehicle
{
    public Truck()
    {
        name = "Truck";
    }
}

This Vehicle program is just example,

So, How can I deserialize specific object (Such as Car, Bike, or Truck) in List of Vehicle in VehicleList class based on value of node Vehicle.


Solution

  • Here is code and results to serialize. XML you cannot have an array as a root element. So in this case it make sense to have two classes : Vehicles and Vehicle. See code below :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    namespace ConsoleApplication107
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                Vehicles vehicles = new Vehicles()
                {
                    vehicles = new List<Vehicle>() {
                        new Car() { make = "BMW"},
                        new Bike() { make = "Buffalo"},
                        new Truck() { make = "MAC"}
                    }
                };
    
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
    
                XmlWriter writer = XmlWriter.Create(FILENAME, settings);
                XmlSerializer serializer = new XmlSerializer(typeof(Vehicles));
                serializer.Serialize(writer, vehicles);
    
            }
        }
    
        public class Vehicles
        {
            [XmlElement("Vehicle")]
            public List<Vehicle> vehicles { get; set; }
        }
        [XmlInclude(typeof(Car))]
        [XmlInclude(typeof(Bike))]
        [XmlInclude(typeof(Truck))]
        public class Vehicle
        {
            public string make { get; set; }
        }
        public class Car : Vehicle
        {
        }
        public class Bike : Vehicle
        {
        }
        public class Truck : Vehicle
        {
        }
    }
    

    Here is results :

    <?xml version="1.0" encoding="utf-8"?>
    <Vehicles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Vehicle xsi:type="Car">
        <make>BMW</make>
      </Vehicle>
      <Vehicle xsi:type="Bike">
        <make>Buffalo</make>
      </Vehicle>
      <Vehicle xsi:type="Truck">
        <make>MAC</make>
      </Vehicle>
    </Vehicles>