Easy C# Custom XML Serialization

Hi everyone,

In the past, I spent time working with XML serialization for Grey: The Lost Technology, and I ended up writing a blog post about my findings and experience with “compressing” data to create smaller xml files, which is seen here: Grey Dev Diary: Problems of Storing Maps.

Now I want to show you a specific method that I use when writing a custom serializer for an object that needs special processing during (de)serialization. First, you would implement the ISerializable interface, and you would need to implement the following functions:

public System.Xml.Schema.XmlSchema GetSchema()
{
    return null;
}

public void ReadXml(XmlReader reader)
{
}

public void WriteXml(XmlWriter writer)
{
}

For me, reading the XML had always been the hardest part, until I came up with this:

public void ReadXml(XmlReader reader)
{
    while (reader.Read())
    {
        if (reader.IsStartElement())
        {
            switch (reader.Name)
            {
                case "Name":
                    Name = reader.ReadElementContentAsString();
                    break;
                case "ValueA" :
                    ValueA = reader.ReadElementContentAsInt();
                    break;
                case "ValueB" :
                    ValueB = reader.ReadElementContentAsInt();
                    break;
                case "DeeperObject":
                    //If object has more information and is its own class, deserialize that one.
                    reader.ReadStartElement();
                    DeepObjectInstance = (ObjectTypeClass)new XmlSerializer(typeof(ObjectTypeClass)).Deserialize(reader);
                    reader.ReadEndElement();
                    break;
                default:
                    //Do something if no case for the start element
                    break;
            }
        }
    }

    //Any sort of post processing
}

The main idea is that you loop through the start element of each entry, and then if you have a case for it, read the values. It’s super simple, and if you need to scale the object you’ve been serializing you won’t break anything.

Writing the XML is just as simple, but you don’t need to loop through anything to do it.

public void WriteXml(XmlWriter writer)
{
    writer.WriteElementString("Name", Name);
    writer.WriteElementString("ValueA", ValueA.ToString());
    writer.WriteElementString("ValueB", ValueB.ToString());

    //Don't forget you can call the WriteXML of another object and serialize it in the
    //same file as the one you're already writing to. It just means more processing later.
    //OtherObject.WriteXml(ref writer);

    writer.WriteStartElement("DeepObject");
    new XmlSerializer(DeeperObjectInstance.GetType()).Serialize(writer, DeeperObjectInstance);
    writer.WriteEndElement();
}

That’s all I have for you! If you have any questions, don’t hesitate to comment!