如何将包含各种对象集合的对象序列化/反序列化为XML?

时间:2013-12-13 10:34:24

标签: c# xml serialization collections

我想序列化一个基本上是其他项容器的类。这些项目是各种对象,但它们都从一个公共类继承。这个例子会更清楚。

我在代码中有这个:

[Serializable]
[XmlInclude(typeof(FileTask))]
[XmlInclude(typeof(DbTask))]
[XmlRoot("task")]
public abstract class TaskBase
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    public TaskBase()
    {
        Name = "Task";
    }
}
[Serializable]
[XmlRoot("fileTask")]
public class FileTask : TaskBase
{
    public FileTask()
    {
        Name = "File Task";
    }
}

[Serializable]
[XmlRoot("dbTask")]
public class DbTask : TaskBase
{
    public DbTask()
    {
        Name = "Db Task";
    }
}

[Serializable]
[XmlRoot("tasks")]
public class TasksConfig : List<TaskBase>
{

}

当我使用以下代码将其序列化为XML时:

        var config = new TasksConfig();
        config.Add(new FileTask());
        config.Add(new FileTask());
        config.Add(new DbTask());
        config.Add(new FileTask());
        config.Add(new DbTask());
        SerializationHelper.SaveToXml<TasksConfig>(config, "milos.xml");

使用此助手类:

 public class SerializationHelper
{
    static public void SaveToXml<T>(T obj, string file)
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("", "");

        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextWriter textWriter = new StreamWriter(file))
        {
            serializer.Serialize(textWriter, obj, ns);
        }
    }
}

我得到了这个结果:

<?xml version="1.0" encoding="utf-8"?>
<tasks>
  <TaskBase d2p1:type="FileTask" name="File Task" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <TaskBase d2p1:type="FileTask" name="File Task" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <TaskBase d2p1:type="DbTask" name="Db Task" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <TaskBase d2p1:type="FileTask" name="File Task" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <TaskBase d2p1:type="DbTask" name="Db Task" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
</tasks>

但是,我想得到这个结果:

<?xml version="1.0" encoding="utf-8"?>
<tasks>
  <fileTask name="File Task" />
  <fileTask name="File Task" />
  <dbTask name="Db Task" />
  <fileTask name="File Task" />
  <dbTask name="Db Task" />
</tasks>

那我怎么能这样做呢?

2 个答案:

答案 0 :(得分:1)

您没有发布TasksConfig班级来源。

像这样:

public class TaskConfig() 
{
    public TaskConfig()
    {
       this.Items = new List<TaskBase>();
    }

    [XmlArray]
    [XmlArrayItem(ElementName="FileTask", Type=typeof(FileTask))]
    [XmlArrayItem(ElementName="DbTask", Type=typeof(DbTask))]
    public List<TaskBase> Items
    {
       get;
       set;
    }
}

然后,为了序列化,你可以这样做:

static void Main(string[] args)
{
    var config = new TasksConfig();
    config.Items.Add( new FileTask() { /* properties */ });
    config.Items.Add( new DbTask() { /* properties */ });

    XmlSerializer serializer = new XmlSerializer(typeof(TasksConfig));
    MemoryStream memoryStream = new MemoryStream();
    serializer.Serialize(memoryStream, config);

    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
    String serializedString = enc.GetString(memoryStream.ToArray());
}

答案 1 :(得分:1)

另一个变体是像这样改变TaskConfig

[Serializable]
[XmlRoot("tasks")]
public class TasksConfig
{
    [XmlElement(typeof(DbTask)), XmlElement(typeof(FileTask))]
    public List<TaskBase> list = new List<TaskBase>();

    public void Add(TaskBase item){
        list.Add(item);
    }

}