Xml Serialization
Object serialization is an important topic which is quite powerful if used correctly. Serialization allows programms to persist objects by storing then in files. In the case of Xml serialization, into Xml files. Xml has become the standard for storage in the recent years and its good to see that with Xml serialization built into the .NET framework, it will be very simple to build applications which can interop well with any other software, Microsoft or not.
XML Serialization Attributes
First we'll start with a code sample of our class which we will serialize and then go on to explain what it does:
using System;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
// Shopping list class which will be serialized
[XmlRoot("shoppingList")]
public class ShoppingList {
private ArrayList listShopping;
public ShoppingList() {
listShopping = new ArrayList();
}
[XmlElement("item")]
public Item[] Items {
get {
Item[] items = new Item[ listShopping.Count ];
listShopping.CopyTo( items );
return items;
}
set {
if( value == null ) return;
Item[] items = (Item[])value;
listShopping.Clear();
foreach( Item item in items )
listShopping.Add( item );
}
}
public int AddItem( Item item ) {
return listShopping.Add( item );
}
}
// Items in the shopping list
public class Item {
[XmlAttribute("name")] public string name;
[XmlAttribute("price")] public double price;
public Item() {
}
public Item( string Name, double Price ) {
name = Name;
price = Price;
}
}
On first glance, this class appears to be a normal class without anything out of the ordinary in the code, but when we look at the method signatures, we see that there are attributes around it such as [XmlRoot], [XmlElement] and [XmlAttribute]These are necessary for any class that will be serialized. This is the magic which allows us to specify how the class will be serialized and what will be elements or attributes and how everything will be named.
Some other useful attributes are:
[XmlIgnore] - this will cause the serializer to ignore the property during serialization. This will exclude it from the XML.
Serialzation
Now here's the cool part. This is how serialization works:
ShoppingList myList = new ShoppingList();
myList.AddItem( new Item( "eggs",1.49 ) );
myList.AddItem( new Item( "ground beef",3.69 ) );
myList.AddItem( new Item( "bread",0.89 ) );
// Serialization
XmlSerializer s = new XmlSerializer( typeof( ShoppingList ) );
TextWriter w = new StreamWriter( @"c:\list.xml" );
s.Serialize( w, myList );
w.Close();
// Deserialization
ShoppingList newList;
TextReader r = new StreamReader( "list.xml" );
newList = (ShoppingList)s.Deserialize( r );
r.Close();
The first chunk of code is simply creating an instance of the ShoppingList class and populating it. After that, we have the serialization part. Here is where the object gets converted into XML. As you can see, all it requires is the use of the XmlSerializer class which is set to serialize anything of type ShoppingList (look at the constructor). The serializer does its work when the Serialize method is called and will output XML to any stream. In this case, we have it output to a file.
Next there is the deserialization part. Here we use the same serializer (since it's set to the right type) and we read in an XML file and the Deserialize method will create the appropriate ShoppingList class object. This code sample shows serialization from a file, but you could just as easily do it from an http stream.
xsd.exe
Now I want to highlight the a useful utility. xsd.exe is a utility to generate schema or class files from given source. It is included with the .NET Framework. There are three main uses for xsd.exe.
First, xsd.exe <schema>.xsd which will create source code for the appropriate class to de-serialize your object.
Second, xsd.exe <assembly>.dll|.exe is used to read the code and generate a schema (.xsd) file for you.
Finally, xsd.exe <instance>.xml|.xdr which will try to infer an .xsd file which you can then use to create an appropriate class.
From a command prompt, type: "xsd.exe" to get more help information.
Conclusion
So there you have it. XML Serialization in C#. This is an incredibly useful way for application developers to persist objects by storing them in a file. It makes it really simple for any programmer to save configuration settings into XML files or application documents as well.
Tips:
- only typed arrays can be serialized and deserialized. If you have any collections such as an ArrayList, you will have to convert it an array. Another alternative is to tell the XmlSerializer what type the ArrayList is with this attribute: [XmlElement("item", typeof(Item))]
- Another very useful attribute I forgot to mention is the [XmlText] attribute. It will cause the field to become the text between an xml element.
Notes:
- This was originally written and posted here: https://www.devhood.com/public.aspx?user_id=00014A50872078CB, but I'd like to archive this on this blog.
Comments
- Anonymous
July 16, 2004
I am working on some Xml Serialization. Here is the problem.
I have a class Person --> everything works great.Then I add a class
public class People : System.Collections.Generic.Collection<Person>
When I try to Serialize this, it works very well, but the Element Name is:
<ArrayOfPerson>, and I need it to be <People>.
The The XmlArray attribute does not really work, and the documentation is unclear on generics. Perhaps this is because it is Beta stuff, but it would be really nice to have this work the same way as an ArrayList, as generics are absolutely fantastic.
Any pointers? - Anonymous
July 16, 2004
And the answer is to use an XmlRoot Attribute on the class. Sorry to trouble you...