Archives

Previous Archive

01 Sep - 30 Sep 2003
01 Oct - 31 Oct 2003
01 Nov - 30 Nov 2003
01 Jan - 31 Jan 2004
01 Feb - 28 Feb 2004
01 Mar - 31 Mar 2004
01 May - 31 May 2004
01 June - 30 June 2004
01 Jul - 31 Jul 2004
01 Nov - 30 Nov 2004
01 Jan - 31 Jan 2005
01 Apr - 30 Apr 2005
01 May - 31 May 2005
01 Jul - 31 Jul 2005
01 Aug - 31 Aug 2005
01 Sep - 30 Sep 2005
01 Oct - 31 Oct 2005
01 Nov - 30 Nov 2005
01 Dec - 31 Dec 2005
01 Jan - 31 Jan 2006
01 Feb - 28 Feb 2006
01 Mar - 31 Mar 2006
01 May - 31 May 2006
01 June - 30 June 2006
01 Aug - 31 Aug 2006
01 Sep - 30 Sep 2006

Last Comments

cheap lexapro (Refactoring): It is very important for you to click below. Trust …
generic soma1988 (Refactoring): askljdIt is very important for you to click below. …
cheap tramadol842… (Glade 3 in MonoDe…): irlgipIt is very important for you to click below. …
zyban (MonoDevelop impro…): It is very important for you to click below. Trust …
buycelexa (Designing menus): It is very important for you to click below. Trust …
cheap tramadol (Designing menus): It is very important for you to click below. Trust …
cialis (Back from holiday…): It is very important for you to click below. Trust …
generic cialis (So many news in M…): It is very important for you to click below. Trust …
sales (Refactoring): World of Warcraft Gold,Wow Gold,Cheap World of Warc…
a roulette wheel (Namibia): I must win this battle. You should help

Last Referrers

17:07 mp3clank.com/viewtopic.php
17:05 galleries.asstraffic.com/alyss…
17:05 galleries.allinternal.com/dora…
17:04 mp3s.good.one.pl/download-mp3-…
16:51 209.85.141.104/search
16:50 bmwz.ru
16:47 newmusiccentre.co.uk/db/rock/e…
16:46 moldovamap.ru/maps/igodownload…
16:39 mp3s.good.one.pl/download-mp3-…
16:37 lipodrene.info

Links

Google
Pivot

To change this list, edit the file '_aux_link_list.html' in your pivot's templates folder.

Stuff

Powered byPivot - 1.24.3: 'Arcee' 
XML Feed (RSS 1.0) 

About

This is the default template for Pivot. You can change this text by editing the file templates/frontpage_template.html in your pivot folder.

Linkdump

+ 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:

public interface IXmlSerializable { void ReadXml (XmlReader reader); void WriteXml (XmlWriter writer); XmlSchema GetSchema (); }

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:

public class CustomHashtable : IXmlSerializable { Hashtable data = new Hashtable (); ... public void WriteXml (XmlWriter writer) { // There must be only on root element writer.WriteStartElement ("data"); foreach (DictionaryEntry entry in data) { writer.WriteElementString ((string)entry.Key, (string)entry.Value); } writer.WriteEndElement (); } public void ReadXml (XmlReader reader) { // Reads the element enclosing the object reader.ReadStartElement(); reader.MoveToContent (); // Reads the "data" element reader.ReadStartElement ("data"); reader.MoveToContent (); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Element) { string key = reader.LocalName; data [key] = reader.ReadElementString (); } else reader.Skip (); reader.MoveToContent (); } reader.ReadEndElement (); } public XmlSchema GetSchema () { XmlSchema s = new XmlSchema (); s.TargetNamespace = "http://www.go-mono.org/schemas"; s.Id = "monoschema"; XmlSchemaElement e = new XmlSchemaElement (); e.Name = "data"; s.Items.Add (e); XmlSchemaComplexType cs = new XmlSchemaComplexType (); XmlSchemaSequence seq = new XmlSchemaSequence (); XmlSchemaAny any = new XmlSchemaAny (); any.MinOccurs = 0; any.MaxOccurs = decimal.MaxValue; seq.Items.Add (any); cs.Particle = seq; e.SchemaType = cs; return s; } }

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:

public class MyTestClass { public string name; public CustomHashtable properties = new CustomHashtable(); }

then the result of a serialization could be something like:

<MyTestClass> <name>a name</name> <properties> <data> <one>1</one> <two>2</two> <three>3</three> </data> </properties> </MyTestClass>

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:

<MyTestClass> <name>a name</name> <properties> <schema targetNamespace="http://www.go-mono.org/schemas" id="monoschema" xmlns="..."> <element name="data"> <complexType> <sequence> <any minOccurs="0" maxOccurs="unbounded"/> </sequence> </complexType> </element> </schema> <data> <one>1</one> <two>2</two> <three>3</three> </data> </properties> </MyTestClass>

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:

public class MyTestClass { [XmlAttribute] public string Name; [XmlIgnore] public Hashtable Data = new Hashtable(); } and I want an output like: <MyTestClass Name="a name"> <one>1</one> <two>2</two> <three>3</three> </MyTestClass>

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 writers

So, 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:

mono genxs.exe myclass.config

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:

<configuration> <serializer class="MyTestClass" assembly="sam.dll"> <writerHooks> <hook type="elements"> <select> <typeName]MyTestClass</typeName> </select> <insertAfter> foreach (DictionaryEntry de in $OBJECT.Data) { Writer.WriteStartElement ((string)de.Key); Writer.WriteString ((string) de.Value); Writer.WriteEndElement (); } </insertAfter> </hook> </writerHooks> <readerHooks> <hook type="unknownElement"> <select> <typeName>MyTestClass</typeName> </select> <replace> string _key = Reader.LocalName; ob.Data [_key] = Reader.ReadElementString (); </replace> </hook> </readerHooks> </serializer> </configuration>

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:

class MyTestClassSerializer : XmlSerializer { protected override void Serialize (object o, XmlSerializationWriter writer) { MyTestClass_Writer xsWriter = writer as MyTestClass_Writer; xsWriter.WriteTree ((MyTestClass)o); } protected override object Deserialize (XmlSerializationReader reader) { MyTestClass_Reader xsReader = reader as MyTestClass_Reader; return xsReader.ReadTree (); } protected override XmlSerializationWriter CreateWriter () { return new MyTestClass_Writer (); } protected override XmlSerializationReader CreateReader () { return new MyTestClass_Reader (); } }

+ 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.