Search code examples
c#linq-to-xml

Import XML with a non typical format to a class


I need to import a XML file looking like this:

<Carpark>
   <Trucks>
      <Truck brand='Chrysler' kg='2100'/>
   </Trucks>
   <Cars>
      <Car brand='Mercedes' kg='1100'/>
   </Cars>
   <Tractors>
      <Tractor brand='John Deere' kg='1500'/>
   </Tractors>
</Carpark>

Essentially I want to have a list of Carpark like this:

public class Carpark
{
    // Type can be for example Truck, Car
    public string Type { get; set; }
    public string Brand { get; set; }
    public int Weight { get; set; }
}

I don't understand how to convert this XML file to the class I want.

What I have tried is:

XElement xElement = XElement.Load(filePath);
IEnumerable<Carpark> carpark = xElement.Elements();

foreach(var vehicle in carpark)
{
    // Once I wrote out the line I was confused as to how to proceed
    Console.WriteLine(vehicle.ToString());
}
      

Solution

  • You can do that with Linq_To_XML and I believe with NewtonsoftJSON:

    void Main()
    {
        var xml = XElement.Parse(x)
            .DescendantsAndSelf("Carpark")
            .Descendants()
            .Where(xe => xe.HasAttributes)
            .Select(xe => new Carpark {
                Type = xe.Name.ToString(),
                Brand = (string)xe.Attribute("brand"),
                Weight = (int)xe.Attribute("kg")
            })
            ;
            
        foreach (var cp in xml)
        {
            Console.WriteLine($"{cp.Type}, {cp.Brand}, {cp.Weight}");
        }
        
    }
    
    static readonly string x = @"<Carpark>
       <Trucks>
          <Truck brand='Chrysler' kg='2100'/>
       </Trucks>
       <Cars>
          <Car brand='Mercedes' kg='1100'/>
       </Cars>
       <Tractors>
          <Tractor brand='John Deere' kg='1500'/>
       </Tractors>
    </Carpark>";
    
    public class Carpark
    {
        // Type can be for example Truck, Car
        public string Type { get; set; }
        public string Brand { get; set; }
        public int Weight { get; set; }
    }