Pages

Sunday, May 29, 2005

Convert XML data to object and back using serialization

Introduction


Saving XML to a class object gives greater flexibility and maintainability. Moreover, it’s the preferred way of returning data from web services as compared to using DataSets. Saving XML to a class object is called serialization and reading back using the reverse process is named as deserialization.


Process\sample


Let's take an example of an XSD named Emp.XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Emp">
<xs:complexType>
<xs:sequence>
<xs:element name="EmpInfo" type="EmpInfo"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="EmpInfo">
<xs:sequence>
<xs:element name="Code" type="requiredString"/>
<xs:element name="FirstName" type="requiredString"/>
<xs:element name="LastName" type="requiredString"/>
<xs:element name="Destination" type="requiredString"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="requiredString">
<xs:annotation>
<xs:documentation>template for required strings</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="optionalString">
<xs:annotation>
<xs:documentation>template for optional strings</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>


Now, to convert a class from XSD, we would run the following command:

xsd C:\Emp.xsd /t:lib /l:cs /c


from the Visual Studio .NET 2003 command prompt. This would create a class file named Emp.


EMP Class

//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.2032

//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
// 
// This source code was auto-generated by xsd, Version=1.1.4322.2032.
//
using System.Xml.Serialization;
/// <remarks/>
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public class Emp {

/// <remarks/>
public EmpInfo EmpInfo;
}

/// <remarks/>
public class EmpInfo {

/// <remarks/>
public string Code;

/// <remarks/>
public string FirstName;

/// <remarks/>
public string LastName;

/// <remarks/>
public string Destination;
}


Now, we could save an employee XML data to this class using the function:

  /// <summary>
/// Returns an emp xsd class object based on the xml data passed
/// </summary>
/// <param name="xml">xml data of employee</param>
/// <returns></returns>
public Emp EmpObject(string xml)
{
StringReader stream = null;
XmlTextReader reader = null;
try
{
// serialise to object
XmlSerializer serializer = new XmlSerializer(typeof(Emp));
stream = new StringReader(xml); // read xml data
reader = new XmlTextReader(stream); // create reader
// covert reader to object
return (Emp)serializer.Deserialize(reader);
}
catch
{
return null;
}
finally
{
if(stream != null) stream.Close();
if(reader != null) reader.Close();
}
}


And to get the XML based on the Emp class object, use the following function:

  /// <summary>
/// Returns the xml as string based on emp object values
/// </summary>
/// <param name="emp">object that would be converted into xml</param>
/// <returns></returns>
public string EmpXml(Emp emp)
{
MemoryStream stream = null;
TextWriter writer = null;
try
{
stream = new MemoryStream(); // read xml in memory
writer = new StreamWriter(stream, Encoding.Unicode) ;
// get serialise object
XmlSerializer serializer = new XmlSerializer(typeof(Emp));
serializer.Serialize(writer, emp); // read object
int count = (int) stream.Length; // saves object in memory stream
byte[] arr = new byte[count];
stream.Seek(0, SeekOrigin.Begin);
// copy stream contents in byte array
stream.Read(arr, 0, count);
UnicodeEncoding utf = new UnicodeEncoding(); // convert byte array to string
return utf.GetString(arr).Trim();
}
catch
{
return string.Empty;
}
finally
{
if(stream != null) stream.Close();
if(writer != null) writer.Close();
}

}
Source : www.codeproject.com/soap/XmlToClassAndBack.asp