Introduction
It is getting more and more common to use Service Oriented Architecture for writing applications. In some cases, we even base our domain model on XML. From this will arise the need for .NET classes to represent such XML structures as strongly-typed objects.
Background
The easiest, most common way to implement an XML serializable object, is through declarative, Reflection based serialization. Program elements such as classes and properties are decorated with attributes that declare how to serialize this program element as XML. XmlSerializer
is then used to generate objects from XML, and serialize objects to XML.
The other approach is to implement the IXmlSerializable
interface, and manually parse the XML using XmlReader
. This gives better performance and more control than declarative serialization, but it is harder to implement.
I wrote this XmlObject
class, and friends, to help implementing IXmlSerializable
based serialization, with as little effort as possible.
When To Use
If you have had the need to generate code from XML Schema, maybe you have tried out xsd.exe, and are not happy with the results. You could then look into generating code yourself, if you need more control of serialization, or if performance is of importance to you.
The XmlObject
class is good for serving as the base class for XML Schema generated code, or generally just to represent some XML structure as an object.
If you use WCF, XmlObject
derived classes are perfect to use with service contracts. The serialization/deserialization process will be performed seamlessly.
Usage
If you have used the Simple API for XML (SAX) before, you know that this approach is easier to use than XmlReader
, although XmlReader
is more efficient. I have tried to combine these strategies.
The following classes are part of the implementation:
XmlObject
This class implements IXmlSerializable
, for fast XML reading and writing. When you derive this class, this class will "drive" the XML parsing process, and it will completely handle the XML generation process. You can override methods like ReadAttribute
, ReadElement
, or ReadText
to "listen" for the specific content you are interested in. You typically use strongly typed properties for specific properties in your objects. However, these will not use backing fields, but instead, work with the Attributes
and Elements
dictionaries.
XmlNodeDictionary
This class is basically just a Dictionary<XmlQualififiedName, object>
. The XmlObject
has two properties of this type: Attributes
and Elements
. These properties can be used to access attributes and elements, respectively.
XmlCodeContentType<E>
Enumerations are very common in XML and XML Schema. It is also very common to make these extensible, so that you can choose a value from a pre-defined set, but you may also specify any normalized string
value that is not pre-defined in this enumeration. For instance, like this:
<xsd:union memberTypes="ObjectiveActionCodeEnumType xsd:normalizedString"/>
xsd.exe will automatically convert properties of that type into string
s. However, XmlCodeContentType
is a class for representing this type of strongly typed constructs.
XmlEnum<E>
A static
utility class which will come in handy when parsing XML code lists to CLR enums.
Conclusion
If you need high-performant XML serializable objects in your solution, you might want to have a look. Feel free to give me some feedback or ask a question.
The attached source code contains a simple example, but let me know if you want to see something from the real world.
History
- February 24, 2009 - 1.0.0.0
- February 24, 2009 - 2.0.0.0
- Fixed article incoherency/article improvement