Building an Xml Serialization Provider

October 13th, 2008 by John Sedlak Leave a reply »

I am a big proponent for delegation of responsibilities and so the Serialize function is nothing more than a redirection to a reuseable internal method.

1
2
3
4
5
6
7
8
9
10
11
public XmlNode Serialize(object obj, XmlDocument doc)
{
    XmlNode node = null;
 
    if (obj == null)
        return null;
 
    node = CreateNode(obj, doc);
 
    return node;
}

The CreateNode function needs to figure out what to do with the object and then do it. The first thing it does is find out if the object can be deserialized. This is done by looking for the XmlNodeAttribute on the object itself. If it is found, we create the element with the Name property of that attribute. Note that where I have placed return null statements would be a good place to throw exceptions or handle the errors nicely.

1
2
3
4
5
6
7
8
9
10
11
12
13
private XmlNode CreateNode(object obj, XmlDocument doc)
{
    XmlNode node = null;
 
    if (obj == null)
        return null;
 
    XmlNodeAttribute nodeAttribute = GetAttribute<XmlNodeAttribute>(obj);
 
    if (nodeAttribute == null)
        return null;
 
    node = doc.CreateElement(nodeAttribute.Name);

The next line is one of the most crucial steps and one of the biggest problem creators in the process. I have yet to come up with a good way of storing the types in the Xml file without demanding complete control over the creation of the file. Thus for now, I simply append an attribute to the Xml element.

1
AppendTypeAttribute(obj, doc, node);

The last portion of the CreateNode method is the true meat and bones. We need to loop through the properties of the object and serialize each one. This is where that enumeration comes in handy. If the property is declared to be a complex type, we recursively call the CreateNode function. On the other hand, if the property is a simple type, we call another method which will simply serialize the data into an XmlNode object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
 
    foreach (PropertyInfo info in properties)
    {
        XmlNodeAttribute propertyNodeAttribute = GetAttribute<XmlNodeAttribute>(info);
 
        if(propertyNodeAttribute == null)
            continue;
 
        object objToSerialize = info.GetValue(obj, null);
 
        if (objToSerialize == null)
            continue;
 
        switch (propertyNodeAttribute.NodeType)
        {
            case XmlNodeType.Complex:
                node.AppendChild(CreateNode(objToSerialize, doc));
                break;
            case XmlNodeType.Simple:
                node.AppendChild(CreateSimpleNode(objToSerialize, propertyNodeAttribute, doc));
                break;
        }
    }
 
    return node;
}

Next up, the CreateSimpleNode and AppendTypeAttribute methods!

Advertisement

Leave a Reply

You must be logged in to post a comment.