views:

1888

answers:

3

What are different ways in which we can XML serialize multiple objects of same/different types?

For example, Generic List<T> for same type of objects and ArrayList for different type of objects.

Also, which type of structures are XML serializable and which are not?

It would be helpful if anyone can provide with sample piece of code or a link.

A: 

You could make all your classes implement System.Xml.Serialization.IXmlSerializable. You could then have a generic collection of this type. It is then very simple to implement the ReadXml and WriteXml methods required.

e.g.

class MyClass : IXmlSerializable
{
        public System.Xml.Schema.XmlSchema GetSchema()
        {            
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            //TODO: read logic here...
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            //TODO: write logic here...
        }
}

Usage...

class WorkerClass
{
  public void SerializeListToFile(IList<IXmlSerializable> list, string fileName)
  {
    using (XmlWriter writer = new XmlTextWriter(fileName))
    {
      foreach (IXmlSerializable item in list)
        item.WriteXml(writer);

      writer.Close();
    }
  }
}
Chris Arnold
A: 

Here is a link for Xml serialization of collections. But Chris Arnold is right implementing IXmlSerializable will allow you to have full control on the serialization. Xml attributes are attractive because they are declarative but the other option is worth learning (and is faster from my experience).

jdehaan
+3  A: 

To be serializable via XmlSerializer, your types must

  • be public
  • have a public parameterless constructor
  • it serializes the public read/write fields and properties (properties being preferred)

In terms of which constructs;

  • individual concrete entities are fine
  • concrete lists/arrays (List<T>, T[], etc) are handled fine
  • but it will struggle with interfaces, dictionaries, and various generics scenarios (other than lists)

You are right that List<T> is fine for serializing a set of like objects. If you are dealing with subclasses, then [XmlInclude] can be used to distinguish types; i.e. if you have:

var list = new List<ParentType>();
list.Add(new ParentType());
list.Add(new ChildType()); // Child : Parent

then this may still be serializable as long as you have:

[XmlInclude(typeof(Child))]
public class Parent {}

public class Child : Parent {}

(you can also specify this relationship in the ctor to XmlSerializer, but it is extra work)

I don't recommend using IXmlSerializable unless you have to; it is complex and hard to get right. More importantly; it doesn't work *at all if you are using wsdl-generated proxy objects over a SOAP service; the other end won't have your IXmlSerializable implementation.

I also don't recommend serializing lists of arbitrary object types; if you have a finite set of known types there are tricks to do this utilising [XmlInclude] etc.

Marc Gravell
The parameterless constructor does not have to be public.
Brian Ortiz