Have you ever tried to parse XML using the .NET framework? I have, and I can never remember the right/wrong way to do it. I normally spend hours on the internet before finding the same solution that I found during my previous attempt. Not anymore! Instead of interacting with the XML directly, convert it to an object that can be easily manipulated. This post shows how to deserialize an XML string into an object and serialize it back into an XML string using attributes from the
System.Xml.Serialization namespace in the target class. The important ones that I've highlighted are XmlRoot, XmlAttribute and XmlElement. They're pretty self explanitory - they basically map a class to a root node, a class member to an attribute within a node and a class member to an element node respectively. When declaring these attributes, you specify the name of the attribute/node used in the string XML to establish the relationship. If your class uses exactly the same naming convention as the XML structure, you could (in theory) leave out these attributes. In most cases, the 2 naming conventions differ. I would recommend using them regardless because it makes your application more future proof. If the name of an element node changes, you only have to update the corresponding attribute instead of renaming a class member which could cause problems elsewhere (in the same or even other applications).
This example includes a utility class with 2 important methods - DeserializeObject and SerializeObject. Both use generics so you pass the target class when calling either method. The XML sample can be deserialized to create a Person object. Alternatively, an existing Person object can be serialized to create a similar XML structure.
Utility class:
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public class XMLSerializationUtility
{
public static T DeserializeObject<T>( Encoding encoding, string xml )
{
try
{
using (MemoryStream memoryStream = new MemoryStream( StringToByteArray( encoding, xml ) ) )
{
using ( XmlTextWriter xmlTextWriter = new XmlTextWriter( memoryStream, encoding ) )
{
XmlSerializer xmlSerializer = new XmlSerializer( typeof( T ) );
return (T)xmlSerializer.Deserialize( memoryStream );
}
}
}
catch
{
return default( T );
}
}
public static string SerializeObject<T>( Encoding encoding, T obj )
{
try
{
MemoryStream memoryStream = new MemoryStream();
using ( XmlTextWriter xmlTextWriter = new XmlTextWriter( memoryStream, encoding ) )
{
XmlSerializer xmlSerializer = new XmlSerializer( typeof( T ) );
xmlSerializer.Serialize( xmlTextWriter, obj );
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
}
return ByteArrayToString( encoding, memoryStream.ToArray() );
}
catch
{
return string.Empty;
}
}
private static Byte[] StringToByteArray( Encoding encoding, string xml )
{
return encoding.GetBytes( xml );
}
private static string ByteArrayToString( Encoding encoding, byte[] byteArray )
{
return encoding.GetString( byteArray );
}
}
Person class:
using System;
using System.Xml.Serialization;
[XmlRoot( "person" ) ]
public class Person
{
private Guid _id;
[XmlAttribute( "id" )]
public Guid ID;
{
get { return _id; }
set { _id = value; }
}
private string _name;
[XmlElement( "Name" )]
public string Name;
{
get { return _name; }
set { _name = value; }
}
private DateTime _dateOfBirth;
[XmlElement( "dob" )]
public DateTime DateOfBirth;
{
get { return _dateOfBirth; }
set { _dateOfBirth = value; }
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<person id="0ADD2974-B14E-440B-B435-C0AF65E57ACF">
<name>Andrew Gunn</name>
<dob>1985-08-08T12:00:00Z</dob>
</person>
Deserialize string XML into a Person object:
Person person = XMLSerializationUtility.DeserializeObject<Person>( Encoding.UTF8, xml );
Serialize a Person object into string XML:
string xml = XMLSerializationUtility.SerializeObject<Person>( Encoding.UTF8, Person );