Click here to Skip to main content
12,698,899 members (22,939 online)
Click here to Skip to main content
Add your own
alternative version

Stats

15.3K views
291 downloads
14 bookmarked
Posted

Keldyn XmlFormatter

, 19 Aug 2010 MIT
Rate this:
Please Sign up or sign in to vote.
A .NET IFormatter which serializes to and from XML

The original article at our homepage.

Introduction

While developing for Keldyn Interactive (former Furie Entertainment), we saw the need for a good dynamic serialization method which would be usable during development, when code changes rapidly. No matter how much the code changes, we always want to be able to restore the previously serialized data. Therefore we developed our own formatter, which we will now share with you.

The XmlFormatter is a .NET formatter (IFormatter) which simply put can serialize an object into an XML document or the other way around; deserialize an object from an XML document. Although there already exist several other alternatives, this XmlFormatter focuses on being practical for in-development projects. The most important feature is that the document can be loaded in most cases even though the source code has been changed since the object was serialized. This means that you can store your objects to the disk, make changes to the source code, and then load the objects back into the program again. However, at times the source code will be so different from when the object was serialized that the serializer won't be able to deserialize it properly. For this, we have designed the XML format to be easily human editable, so you can simply open up the XML document and change it so that it works again. This is especially useful if the data is critical and you "just have to get it into the program again" (which would be impossible if you used for example the binary formatter).

Usage Example

To use the formatter, we first need something to serialize. This is a simple class to demonstrate some of the features, although the formatter handles most of the things any other IFormatter handles.

[Serializable]
class Test
{
    public String String { get; set; }
    int integer = 0;
    public int Integer { get { return integer; } set { integer = value; } }
    public List<Test> Children { get; set; }
}

Next, we demonstrate how to use the formatter to serialize and deserialize.

Test o = new Test
{
    String = "MyTest",
    Integer = 5,
    Children = new List<Test>
    {
        new Test { String = "Child1" },
        new Test { String = "Child2" }
    }
};
XmlFormatter formatter = new XmlFormatter();
MemoryStream m = new MemoryStream();
formatter.Serialize(m, o);
m.Position = 0;
Test d = (Test)formatter.Deserialize(m);

Document Persistence (Optional Feature)

If the serialized objects are version controlled, you generally want the documents to change as little as possible when you load, update and then re-serialize them. To ensure this, we have the PersistenceData property in the XmlFormatter. When you deserialize, this object is created and you have to store it somewhere, and later assign it to the PersistanceData property again. This will minimize the changes done in the document. Note that this is an optional feature.

Test d = (Test)formatter.Deserialize(s);
XmlFormatterPersistenceData p = formatter.PersistenceData;
// Then, once you want to serialize the object again:
formatter.PersistenceData = p;
formatter.Serialize(m, d);

Features

  • Stores the objects in human readable XML, which means that you can easily edit your stored resources.
  • A very generous type and field name resolver, which means that you can serialize an object, change your source code and then load the object again, and in most cases it will work. Fields and properties that have been removed will be ignored, new ones will have their default value.
  • Lists, Arrays and Dictionaries are all handled explicitly in the formatting to give an even cleaner XML document.
  • Is culture invariant, i.e. it doesn't matter if you store the data on a Swedish system and then open it on an American system.
  • Version control friendly (Subversion, Git, Darcs, etc.). Minimal changes are ensured to occur in a re-serialized document, especially if you use the document persistence feature.
  • You can specify your own error callback function. The default behavior is to throw an exception, but you may want to handle errors in the XML files in other ways. Note though that this feature is somewhat incomplete.

Limitations

  • In spite of how a formatter "should" work, we construct objects during deserialization by calling their constructor. We found this to be useful in a scenario where you want to reset parts of the class; all you have to do is to delete those elements in the XML file and those properties or fields will be reassigned their default value.
  • The SurrogateSelector is currently not implemented.

Alternatives

This is nowhere near an extensive list of XML serializers, but these are some of the alternatives to our class, and what we feel are their limitations compared to ours.

  • System.Xml.Serialization.XmlSerializier: The problem with this class is that it does not support the ISerializable interface and Serializable attribute, and that it doesn't really support very complex scenarios.
  • Patrick Boom's XMLFormatter: This formatter needs to know the type of the object we are trying to deserialize. This can be a problem if we work with interfaces and polymorphic classes.
  • System.Runtime.Serialization.Formatters.Soap.SoapFormatter: The output of this formatter is not very human readable and thus is hard to edit. 
  • YAXLib: This library is more targeted towards generating clear and readable XML documents. Does not support the IFormatter interface or the ISerializable interface.

Conclusion

And that's it! If you have any questions or find any bugs, don't hesitate to write a line below or send us an email.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Fredrik Norén
CEO Keldyn Interactive
Sweden Sweden
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionCrashes Pin
Member 374574324-Apr-12 8:54
memberMember 374574324-Apr-12 8:54 
QuestionSuperb! Pin
PokeADonkey29-Feb-12 10:25
memberPokeADonkey29-Feb-12 10:25 
GeneralMy vote of 4 Pin
Eddy Vluggen17-Apr-11 7:44
memberEddy Vluggen17-Apr-11 7:44 
GeneralMy vote of 4 Pin
Pranay Rana19-Aug-10 23:28
memberPranay Rana19-Aug-10 23:28 
GeneralMy vote of 3 Pin
sam.hill19-Aug-10 6:08
membersam.hill19-Aug-10 6:08 
GeneralRe: My vote of 3 Pin
Fredrik Norén19-Aug-10 22:52
memberFredrik Norén19-Aug-10 22:52 
GeneralRe: My vote of 3 Pin
sam.hill20-Aug-10 6:06
membersam.hill20-Aug-10 6:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170118.1 | Last Updated 20 Aug 2010
Article Copyright 2010 by Fredrik Norén
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid