Search code examples
c#xmlxml-serializationxml-deserialization

Cannot parse simple XML into an object?


XML

<MeterWalkOrder>
  <Name>Red Route</Name>
  <Meters>
    <Meter>
      <MeterID>1</MeterID>
      <SerialNumber>12345</SerialNumber>
    </Meter>
    <Meter>
      <MeterID>2</MeterID>
      <SerialNumber>SE</SerialNumber>
    </Meter>
  </Meters>
</MeterWalkOrder>

I cannot get simple XML into an object using any serializer

var xml = File.ReadAllText("WalkOrder.xml");
var xmlSerializer = new NFormats.Xml.XmlSerializer();
var obj = xmlSerializer.Deserialize<MeterWalkOrder>(new StringReader(xml));

I just get back 2 meter objects that have none of the attributes set and the name is not even set in walk order.

 public partial class MeterWalkOrder
 {
        public MeterWalkOrder()
        {
            Meters = new List<Meter>();
        }

        [DataMember]
        public String Name { get; set; }
     }
}

using System;
using System.Xml.Serialization;

namespace WindowsFormsApplication1.Classes
{    
    public class Meter : IMeter
    {
        [XmlAttribute]
        public int MeterID { get; set; }

        [XmlAttribute]
        public String SerialNumber { get; set; }
    }
}

I am willing to try any xml serializer.


Solution

  • First of all i suggest you to read Introducing XML Serialization on MSDN You made a couple of errors which lead to not mentioned exceptions thrown when you run your code.

    1. in your Xml MeterID and SerialNumber are not attributes they are elements. (As Wyat Earp commented)
    2. if you want to serialize something you have to tell that it should be [Serializable]
    3. serialization requires an implemented public empty constructor
    4. dont open streams when you are not closing them (use "using")
    5. To test if your serialization works best first serialize, then check the output and then implement deserialize

    Find a fully working example below:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace X123
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                MeterWalkOrder mo = new MeterWalkOrder();
                mo.Name = "name";
                mo.Meters.Add(new Meter { MeterID = 1, SerialNumber = "kdkdkd" });
                mo.Meters.Add(new Meter { MeterID = 2, SerialNumber = "holladrio" });
    
                var xmlSerializer = new XmlSerializer(typeof(MeterWalkOrder), new Type[] { typeof(Meter) });
                {
                    xmlSerializer.Serialize(File.CreateText("hello.xml"), mo);
                    using (Stream s = File.OpenRead("hello.xml"))
                    {
                        var obj = xmlSerializer.Deserialize(s);
                    }
                }
            }
    
    
    
        }
    
        [Serializable]
        public class MeterWalkOrder
        {
            public MeterWalkOrder()
            {
            }
    
            public string Name { get; set; }
            public List<Meter> Meters { get { return meters; } set { meters = value; } }
            private List<Meter> meters = new List<Meter>();
        }
    
        [Serializable]
        public class Meter
        {
            public Meter()
            {
            }
    
            [XmlAttribute]
            public int MeterID { get; set; }
    
            [XmlAttribute]
            public string SerialNumber { get; set; }
        }