Search code examples
c#xmlserializer

using XmlSerializer with unknown root element


I have some XML files that look like this:

File "B156.xml"

<B156>
  <Customer>
    <Name>The Barn</Name>
    <Phone>0427825166</Phone>
  </Customer>
  <Orders>
    <Item>
      <Description>Black toner</Description>
      <Amount>$59.00</Amount>
    </Item>
  <Orders>
</B156>

File "B172.xml"

<B172>
  <Customer>
    <Name>Pixie Inc</Name>
    <Phone>0426553190</Phone>
  </Customer>
  <Orders>
    <Item>
      <Description>Colour toner</Description>
      <Amount>$79.00</Amount>
    </Item>
  <Orders>
</B172>

How do I use XmlSerializer in this case, considering the root element is dynamic and we cannot use XmlRoot("RootName") to specify it?


Solution

  • You can try this,

    CLASS OBJECT

    [XmlRoot("root")]
    public class CustomerOrder
    {
        public Customer Customer { get; set; }
    
        [XmlArray("Orders")]
        [XmlArrayItem("Item")]
        public List<Order> Orders { get; set; }
    }
    
    public class Customer
    {
        public string Name { get; set; }
        public string Phone { get; set; }
    }
    
    public class Order
    {
        public string Description { get; set; }
        public string Amount { get; set; }
    }
    

    CHANGEROOT METHOD

        private static XmlDocument changeRoot(XmlDocument xmlDocument)
        {
            var newXmlDocument = new XmlDocument();
            var newRoot = newXmlDocument.CreateElement("root");
            newXmlDocument.AppendChild(newRoot);
            newRoot.InnerXml = xmlDocument.DocumentElement.InnerXml;
    
            return newXmlDocument;
        }
    

    SERIALIZATION

            var xmlDocument = new XmlDocument();
            xmlDocument.Load("XMLFile1.xml");
            xmlDocument = changeRoot(xmlDocument);
    
            XmlSerializer serializer = new XmlSerializer(typeof(CustomerOrder));
            CustomerOrder result;
    
            using (TextReader reader = new StringReader(xmlDocument.InnerXml))
            {
                result = (CustomerOrder)serializer.Deserialize(reader);
            }