views:

111

answers:

2

I have a collection of objects and for each object I have its type FullName and either its value (as string) or a subtree of inner objects details (again type FullName and value or a subtree). For each root object I need to create a piece of XML that will be xml de-serializable.

The problem with XmlSerializer is that i.e. following object

int age = 33;

will be serialized to

<int>33</int>

At first this seems to be perfectly ok, however when working with reflection you will be using System.Int32 as type name and int is an alias and this

<System.Int32>33</System.Int32>

will not deserialize.

Now additional complexity comes from the fact that I need to handle any possible data type. So solutions that utilize System.Activator.CreateInstance(..) and casting won't work unless I go down the path of code gen & compilation as a way of achieving this (which I would rather avoid)

Notes: A quick research with .NET Reflector revealed that XmlSerializer uses internal class TypeScope, look at its static constructor to see that it initializes an inner HashTable with mappings.

So the question is what is the best (and I mean elegant and solid) way to workaround this sad fact?

A: 

Why don't you serialize all the field's type as an attribute?

Instead of

<age>
  <int>33</int>
</age>

you could do

<age type="System.Int32">
  33
</age>
Mark P Neyer
Well it actually does not deserialize to an int object.
Piotr Owsiak
+1  A: 

I don't exactly see, where your problem originally stems from. XmlSerializer will use the same syntax/mapping for serializing as for deserializing, so there is no conflict when using it for both serializing and deserializing. Probably the used type-tags are some xml-standard thing, but not sure about that. I guess the problem is more your usage of reflection. Do you instantiate your imported/deserialized objects by calling Activator.CreateInstance ? I would recommend the following instead, if you have some type Foo to be created from the xml in xmlReader:

Foo DeserializedObject = (Foo)Serializer(typeof(Foo)).Deserialize(xmlReader);

Alternatively, if you don't want to switch to the XmlSerializer completely, you could do some preprocessing of your input. The standard way would then be to create some XSLT, in which you transform all those type-elements to their aliases or vice versa. then before processing the XML, you apply your transformation using System.Xml.Xsl.XslCompiledTransform and use your (or the reflector's) mappings for each type.

Simpzon
The problem is that i need to do Xml de-serializatoin form XML that I produce. I have object type from Reflection but XmlSerializer expects <int> rather than <System.Int32>, etc.However you mention XSL-T which will allow me to manipulate mappings and more without re-compilation and that's a huge advantage, thanks.
Piotr Owsiak