Thursday, October 6, 2005

Rapid Development with the XmlSerializer

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/rapid_development_with_the_xmlserializer.htm]

Sometimes you'll want to save your business objects to an xml file. All the Xml parsing and manipulation can be tedious, but the .Net Framework provides a great class to save us from this: XmlSerializer. This class serializes objects (i.e. their internal state, like property values) to and from Xml. You could add methods to your objects like WriteToXml and ReadFromXml to encapsulate this logic. For example, the following employee class has a few methods, and the Xml Serialization methods:

    public class Employee
    {
        public Employee()
        {
        }

    #region Public Properties

        private string _strName;
        public string Name
        {
            get {return _strName;}
            set {_strName=value;}
        }

        private int _intId;
        public int EmployeeId
        {
            get {return _intId;}
            set {_intId=value;}
        }

    #endregion

    #region Public Methods

        public bool AddOrder()
        {
            return true;
        } //end of method

 
    #endregion

    #region Xml Serialization

    public void WriteToXml(string strPath)
    {
      System.Xml.Serialization.XmlSerializer x = new XmlSerializer(typeof(Employee));
      System.IO.StreamWriter sw = null;

      try
      {
        sw = new StreamWriter(strPath);
        x.Serialize(sw,this);
      }
      finally
      {
        if (sw != null)
          sw.Close();
      }
    }

    public static Employee ReadFromXml(string strPath)
    {
      System.Xml.Serialization.XmlSerializer x = new XmlSerializer(typeof(Employee));
      System.IO.StreamReader sr = null;

      try
      {
        sr = new StreamReader(strPath);
        Employee e = (Employee)x.Deserialize(sr);
        return e;
      }
      finally
      {
        if (sr != null)
          sr.Close();
      }
    }

    #endregion

    } //end of class

Both methods require a physical file path. The Write is an instance method that returns void (it writes the current state of the object). The Read is a static method that returns an instance of the type.

Serializing this to Xml produces the following file. Notice how the values of the properties are automatically handled. While this example is a direct mapping of object properties to xml nodes, XmlSerializer provide attributes for more advanced features.

xml version="1.0" encoding="utf-8"?>
<
Employee
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>TimName>
  <EmployeeId>3EmployeeId>

Employee>

We can also verify the read-write integration with the following test. First we create an object, then we save it to Xml, then we read it into another object, and finally compare the properties.

    [Test] public void SaveToXml()
    {
      string strPath = @"C:\temp\emp.xml";

      Employee e= new Employee();
      e.EmployeeId = 3;
      e.Name = "Tim";

      //Save
      e.WriteToXml(strPath);

      //Get
      Employee e2 = Employee.ReadFromXml(strPath);

      Assert.AreEqual(e.EmployeeId,e2.EmployeeId);
      Assert.AreEqual(e.Name,e2.Name);

    }

XmlSerializer makes this easy, and is a useful concept to have.

No comments:

Post a Comment