2013-12-13 32 views
1

我想序列化一個基本上是其他項目的容器的類。這些項目是各種各樣的對象,但它們都從一個普通的類繼承而來。這個例子會更清楚。如何序列化/反序列化包含各種對象集合到XML的對象?

我有這樣的代碼:

[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> 

我怎麼能這樣做呢?

回答

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); 
    } 

} 
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()); 
}