Search code examples
c#xmlconvertersxmldocument

What is the easiest way to convert this XML document to my object?


I have an XMLDocument that i need to read in and convert into a set of objects. I have the following objects

public class Location
{
      public string Name;
      public List<Building> Buildings;
}

public class Building
{
     public string Name;
     public List<Room> Rooms;
}

and i have the following XML file:

 <?xml version="1.0" encoding="utf-8" ?>
 <info>
 <locations>
  <location name="New York">
  <Building name="Building1">
    <Rooms>
      <Room name="Room1">
        <Capacity>18</Capacity>
      </Room>
      <Room name="Room2">
        <Capacity>6</Capacity>
      </Room>
    </Rooms>
  </Building>

  <Building name="Building2">
    <Rooms>
      <Room name="RoomA">
        <Capacity>18</Capacity>
      </Room>
    </Rooms>
  </Building>
</location>
<location name ="London">
  <Building name="Building45">
    <Rooms>
      <Room name="Room5">
        <Capacity>6</Capacity>
      </Room>
  </Building>
</location>
</locations>
</info>

What is the best way of doing this? Should I be serializing the xmldocument to the object automatically or do i need to parse out each element and convert into my object manually? In particular, I am trying to figure out how to convert the collections (locations, buildings, etc).

What is the best suggestion to convert this XML file into basically a

List<Location>

objects?


Solution

  • You could start by fixing your XML because in the example you have shown you have unclosed tags. You might also wrap the <Building> tags into a <Buildings> collection in order to be able to have other properties in this Location class other than buildings.

    <?xml version="1.0" encoding="utf-8" ?>
    <info>
      <locations>
        <location name="New York">
          <Buildings>
            <Building name="Building1">
              <Rooms>
                <Room name="Room1">
                  <Capacity>18</Capacity>
                </Room>
                <Room name="Room2">
                  <Capacity>6</Capacity>
                </Room>
              </Rooms>
            </Building>
    
            <Building name="Building2">
              <Rooms>
                <Room name="RoomA">
                  <Capacity>18</Capacity>
                </Room>
              </Rooms>
            </Building>
          </Buildings>
        </location>
        <location name="London">
          <Buildings>
            <Building name="Building45">
              <Rooms>
                <Room name="Room5">
                  <Capacity>6</Capacity>
                </Room>
              </Rooms>
            </Building>
          </Buildings>
        </location>
      </locations>
    </info>
    

    Once you have fixed your XML you could adapt your models. I would recommend you using properties instead of fields in your classes:

    public class Location
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
    
        public List<Building> Buildings { get; set; }
    }
    
    public class Building
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        public List<Room> Rooms { get; set; }
    }
    
    public class Room
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        public int Capacity { get; set; }
    }
    
    [XmlRoot("info")]
    public class Info
    {
        [XmlArray("locations")]
        [XmlArrayItem("location")]
        public List<Location> Locations { get; set; }
    }
    

    and now all that's left is deserialize the XML:

    var serializer = new XmlSerializer(typeof(Info));
    using (var reader = XmlReader.Create("locations.xml"))
    {
        Info info = (Info)serializer.Deserialize(reader);
        List<Location> locations = info.Locations;
        // do whatever you wanted to do with those locations
    }