How to XML serialize a Generic List<T> containing multiple Types derived from a base class T
-
Wednesday, March 14, 2007 10:12 PMI need to serialize to XML a datastructure based on Generics such as List<T>. The problem arises in that I want T to be a base class for multiple derived classes. When I try to serialize this I cannot get the derived classes to be serialized, only the base Class are serialized.
Eg;
[Serialize]
Class Node{
private string n_info;
}
Class Node_A : Node {
private string a_info;
}
Class node_B : Node {
private string b_info;
}
List<Node> list = new List<Node>();
list.Add(new Node_A());
list.Add(new Node_B());
XmlSerializer serializer = new XmlSerializer(typeof(List<Node>),
new Type[] { typeof(Node_A), typeof(Node_B) });
FileStream fstream = new FileStream("ListData.xml", FileMode.Create, FileAccess.Write, FileShare.None);
serializer.Serialize(fstream, list);
fstream.Close();
This runs but only serializes the Node Base Class attributes.
All Replies
-
Friday, March 23, 2007 9:31 AM
A bit late maybe, but...have you tried the XmlInclude attribute?
You need to set an XmlInclude entry on the base class for each subclass. In your example it would be:...
[Serializable]
[XmlInclude(Node_A)]
[XmlInclude(Node_B)]
Class Node{
private string n_info;
}
...Ugly - yes, but there you go...
//Carl
-
Friday, March 23, 2007 1:18 PM
Just a quick point but all your members are marked 'private' and you can only serialize public members with XmlSerializer. Are you sure that this is not connected to your problem? -
Wednesday, March 28, 2007 9:04 AM
I got it working as follows..
// Create a sample List with test data List<Node> list = new List<Node>();list.Add(
new AppNode("app1"));list.Add(
new DbNode("db1"));// Serialise the list
XmlSerializer serializer = new XmlSerializer(typeof(List<Node>), new Type[] { typeof(AppNode), typeof(DbNode) }); FileStream fstream = new FileStream("List-Node.xml", FileMode.Create, FileAccess.Write, FileShare.None);serializer.Serialize(fstream, list);
fstream.Close();
// Deserialise the listfstream =
new FileStream("List-Node.xml.xml", FileMode.Open, FileAccess.Read, FileShare.None);list.Clear();
list = (
List<Node>)serializer.Deserialize(fstream);fstream.Close();
The Node, AppNode and DBNode are defined as follows:-
[
Serializable] public class Node{
public Node() {} // Required for Serialization
public Node(string nm){
Name = nm;
}
private string m_name = "";
public string Name{
get { return m_name; } set { m_name = value; }}
}
[
Serializable] public class AppNode : Node{
public AppNode() : base() { } // Required for Serializationpublic AppNode(string nm) : base(nm)
{
AppInfo = "Some info about app";
}
private string m_appInfo;
public string AppInfo{
get { return m_appInfo; } set { m_appInfo = value; }}
}
[
Serializable] public class DbNode : Node{
public DbNode() : base() {} // Required for Serialization
public DbNode(string nm) : base(nm)
{
DbInfo = "Some info about database";
}
private string m_dbInfo;
public string DbInfo{
get { return m_dbInfo; } set { m_dbInfo = value; }}
}

