+ 4 - 1 | § ¶Custom xml serialization with IXmlSerializable
IXmlSerializable is an undocumented interface that can be used to provide custom xml serialization support to types that are to be serialized using XmlSerializer. In the MS.NET framework the only class that implements this interface seems to be DataSet.
The IXmlSerializable interface is defined like this:
The use of the first two methods is pretty obvious. XmlSerializer calls WriteXml to serialize the object's data and calls ReadXml to deserialize it. There is only one restriction in the structure of the generated xml: it must contain a single root element.
The third method, GetSchema, is called by the serialization engine when it needs to generate a schema for the type. It would be called, for example, when generating the WSDL document for a web service (the WSDL document must include xml schemas for all data that can be sent as part of a message).
To make it clearer, here is a sample class that implements the IXmlSerializable interface:
Notice that when the runtime calls ReadXml, the reader is positioned over the element that contains your root data element (not over the root element itself), so you need to skip it before starting to read your data.
If this CustomHashtable is included in a class like this:
then the result of a serialization could be something like:
GetSchema can return null, in which case the runtime expects the schema to be embedded in the object's data. Thus, WriteXml should first write the schema and then the element that contains the data. The result should be like this:
Notice that in this case WriteXml is responsible for writing the schema, and ReadXml for reading it. The serialization engine won't do anything for you.
+ 2 - 1 | § ¶Going to Congreso Hispalinux
If my health and work load permits it, I'm going to Madrid to the VI Congreso Hispalinux, from 24th to 27th of September. I hope to meet many friends there!+ 2 - 1 | § ¶Creating custom xml serializers
XmlSerializer and related classes provide a really useful and easy to use framework for reading and writing xml documents. The only thing that I miss on that class is a way to extend it, that is, a way to hook into the xml serialization and deserialization process so I can perform class-specific or even member-specific serialization. Yes, there are plenty of attributes for customizing the xml generation, but sometimes that's not enough.
For example, suppose that I want to serialize instances of a class like the following:
where the "one", "two", "three" elements are entries in the hashtable.
There is no way I can tell XmlSerializer to serialize the Data field as I would like to. This is a "by design" limitation. XmlSerializer was designed to be fast, not to be flexible. When you create a XmlSerializer instance for a given type, the runtime generates and compiles on the fly the code needed to serialize and deserialize objects of that type (that's what MS.NET does, and what Mono will do soon). In fact, in generates two classes, a serializer and a deserializer, derived from XmlSerializationWriter and XmlSerializationReader respectively. However, you can't customize those classes, since they are generated on run time.
You can't? That's half true. You can take the generated code, modify it to your pleasure, and add it to your application. And then your application can create an instance of XmlSerializer and tell it to use the modified reader and writer.
Generating readers and writersSo, the first step is to generate the writer and the reader for the custom serializer. If you are running on MS.NET you can use a trick to get the code that XmlSerializer generates on the fly. If you are using Mono, you're lucky, because you can use the genxs tool to generate the serializer. You would execute:
where myclass.config is a file that contains information about what has to be generated (see genxs' README for more info). It would be something like:
Implementing the XmlSerializer
To tell the XmlSerializer to use a specific reader and writer you have to create a derived class and implement the CreateReader and CreateWriter methods, which should return new instances of the reader and the writer. Notice that the derived class don't need to (in fact must not) tell the XmlSerializer which is the type to be serialized/deserialized, since the reader and writer are already specific for a type.
You must also override the methods Serialize(object,XmlSerializationWriter) and Deserialize(XmlSerializationReader). Those methods should cast the writer/reader to the appropiate type, and serialize/deserialize the object by calling the the methods that the custom reader and writer provide.
The derived XmlSerializer class should be like this:
+ 1 - 2 | § ¶First words
Hello world!I feel that today is a good day to start blogging. I think that this will be a good place to talk about me and my experiencies in the development of the Mono project, specially about my work in Remoting, Binary Serialization, XmlSerializer and Web Services.
Lluis Sanchez.