Introduction
My previous article, Hash Table and Serialization in .NET, describes how the content of a hash table is serialized to and deserialized from a binary file. This article continues the serialization topic, and describes XML serialization in .NET, where objects are serialized and deserialized into and from XML documents.
XML serialization implemented by XMLSerializer
class converts an object's public
classes, properties and fields to a serial XML format. The following example shows how an object of the Person
class is serialized into an XML document.
class Person
{
public Person( string firstName, string lastName )
{
this.firstName = firstName;
this.lastName = lastName;
}
public string firstName;
public string lastName;
}
static void Main()
{
Person person = new Person( "John", "Doe" );
XmlSerializer x = new XmlSerializer( typeof(Person) );
TextWriter writer = new StreamWriter( "person.xml" );
x.Serialize( writer, person );
}
If you run the above example, you will get a runtime error message, System.InvalidOperationException
. The error is caused by the line XmlSerializer x = new XmlSerializer( typeof(Person) );
. As it turns out, the class Person
requires a modifier public
and a default constructor. These are common mistakes that I made while working with XmlSerializer
class. After you add the public
modifier and the default constructor to the Person
class, you will get the following XML elements.
="1.0 encoding="
<Person xmlns:xsd="http:www.w3.org/2001/XMLScheme"
xmlns:xsi="http:www.w3.org/2001/XMLScheme-instance">
<firstName>John</firstName>
<lastName>Doe</lastName>
</Person>
As you can see, the element names in the above XML document reflect the public
member variable names. You may ask what if I want to make the member variables private
. Can I still serialize this class? XmlSerializer
cannot serialize private
members, however, you can use public
properties as the access methods to the private
members as shown below:
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
private string firstName;
private string lastName;
In this case, the XML elements would be FirstName
and LastName
instead of firstname
and lastname
respectively to reflect the property names. You can change the XML element names, so that they are different from the property names by using C# attributes. For example, if you want to change the FirstName
element to MyFirstName
, you can add the following XML element attribute to the FirstName
property.
[XmlElement(ElementName = "MyFirstName")]
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
Now, let's expand on the above concept to a more complex application such as a phone book application as described in my previous article, Hash Table and Serialization in .NET. The following UML class diagram shows the relationships between classes that are part of the application. The Contacts
class contains one or more Contact
, and Contact
class contains a Person
class and a PhoneNumber
class.
The Person
, PhoneNumber
, and Contact
classes are straight forward and self explanatory, so I will not go into the details of these classes. The Contacts
class has a private
hash table member variable table
that takes the Person
object as the key and the Contact
object as the value. Since this hash table member variable contains all of the contacts, it will be nice if it can be serialized directly to a XML document. However, as it turns out, XmlSerializer
does not work with the Hashtable
class because the Hashtable
indexer takes a non-integer parameter (object parameter), and XmlSerializer
expects indexers with only an integer parameter. So in order to serialize all of the contacts to the XML document, the hash table is converted to a Contact
array, and this array is then serialized to an XML document as shown below:
Contact[] aContact = new Contact[table.Count];
table.Values.CopyTo( aContact, 0 );
XmlSerializer x = new XmlSerializer( typeof(Contact[]) );
TextWriter writer = new StreamWriter( "phonebook.xml" );
x.Serialize( writer, aContact );
To deserialize the XML elements from the XML document to the hash table, the above steps will be reversed. The XML elements are first deserialized to a Contact
array, and then each member of the array is added to the hash table as follows:
XmlSerializer x = new XmlSerializer( typeof(Contact[]) );
FileStream fs = null;
try
{
fs = new FileStream( "phonebook.xml", FileMode.Open );
XmlReader reader = new XmlTextReader(fs);
Contact[] contacts = (Contact[]) x.Deserialize( reader );
for ( int i = 0; i < contacts.Length; i++ )
{
Contact contact = (Contact) contacts[i];
table.Add( contact.GetPerson, contact );
}
}
catch( FileNotFoundException )
{
}
finally
{
if ( fs != null ) fs.Close();
}
That is all for now. I hope you enjoy this brief introduction on XML serialization in .NET.
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.