Anjan Saha
Anjan Saha

Reputation: 57

Serialization in C#

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>

Upvotes: 0

Views: 254

Answers (2)

allonym
allonym

Reputation: 1418

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.

Upvotes: 0

Ivan Zlatanov
Ivan Zlatanov

Reputation: 5226

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.

Upvotes: 2

Related Questions