views:

99

answers:

2

My class structure is as follows.

[Serializable]
[XmlRootAttribute("person", Namespace = "", IsNullable = false)]
public class Person : IDisposable
{
      Private int _id;
      Private string _name;

      [XmlElement(“id”)]
      Public int Id
      {
            Get{ return _id;}
            Set{ _id = value;}
      }

      [XmlElement(“name”)]
      Public string Name
      {
            Get{return _name;}
            Set{_name = value;}
      }
}

I am getting the following xml when I serialize the above class

<person> 
 <id>1</id>
  <name>Test</name>
</person>

Now, I would like to serialize the above class as follows i.e. I would like append “type” attribute for each public property that is serialized as xml element. I can append “type” attribute to “person” node by declaring another public property “type” with “[XmlAttribute(“type”)]” but I would like to achieve the same for each public property that is serialized as xml element. Any idea to achieve below:

<person type=”Person”>
  <id type=”int”>1</id>
  <name type=”string”>Test</name>
</person>
+2  A: 

First things comes into my mind is to create a generic class, named for example Typed<T>, which looks like this:

    [Serializable]
    public class Typed<T>
    {
        public Typed()
        {
        }

        public Typed( T value )
        {
             this.Value = value;
        }

        [XmlText]
        public T Value { get; set; }

        [XmlAttribute( "Type" )]
        public String Type
        {
            get
            {
                return typeof( T ).Name;
            }
            set
            {
                // Skipped for clarity
            }
        }
    }

Then your Public int Id, becomes Public Typed<int> Id. There might be another way of doing this involving surrogates for the xml parser, but right now this is on top of my head.

Ivan Zlatanov
+1 crazy alternative! ... add implicit conversions to / from the Typed<T> to T, and you get simpler use :)
eglasius
A: 

Ivan's answer is good, and very creative, but may involve refactoring code that you don't want to touch. If that's the case, you might consider implementing IXmlSerializable. It involves working directly with XmlWriter and XmlReader, but as long as you know the pitfalls of working with these classes (particularly XmlReader) it's not that bad and it gives you supreme control over the format of the XML.

If you want to get fancy you could even write an XmlSerializationWrapper<T> that implements IXmlSerializable and uses reflection to get the [Xml...] attributes of T and its members in order to determine how to format/read the XML, adding/using the type attribute. But at that point it's probably less crazy to just use Ivan's solution.

allonym
Sounds creative; i can well give it a try but then i have to decorate for all built in types. Is this the way to go about?
If you went the generic way, whether or not you would need to decorate for built-in types would depend on how you implement the discovery of serializable members. I would tend to handle it the same way the framework's serialization does: if a property is decorated with an XML attribute, serialize as indicated by the attribute; if decorated with XmlIgnore, don't serialize it; if undecorated, serialize using the property's name as the node name. Adding the type attribute is just a matter of writing out typeof(property).Name.
allonym