2017-08-22 109 views
1

我想用XMLSerializer來生成XML。我有一個正在被其他類繼承的抽象Base類。如何使用XMLSerializer生成XML?

public abstract class Base 
    { 
     public string Name {get; set;} 
     public int ID {get; set;} 

     public Base(string Name, int ID) 
     { 
     this.Name = Name; 
     this.ID = ID; 
     } 
    } 



public class HR: Base 
    {  
     public HR(string Name, int ID): Base(Name,ID) 
     { 
     } 
    } 

    public class IT : Base 
    { 
     public IT(string Name, int ID): Base(Name,ID) 
     { 
     } 
    } 

我不知道如何生成格式

<Employee> 
<HR> 
    <Name> </Name> 
    <ID> </ID> 
</HR> 
<IT> 
    <Name> </Name> 
    <ID> </ID> 
</IT> 
</Employee> 

我的含糊不清的問題道歉的XML。我從來沒有使用過XMLSerializer,也不知道如何繼續使用它。任何幫助將不勝感激。

感謝

+0

您的課程還存在其他一些錯誤。你在'Employee'基類中定義'ID'是一個'string',但在'HR'類和'IT'類中,你傳遞一個'int'作爲ID。另外,爲了調用基類,你應該使用'base(Name,ID)'而不是'Employee(Name,ID)'。 – nbokmans

+0

@nbokmans道歉。這只是一個錯字。我現在編輯並更新了代碼。感謝您指出。 – Sugan88

+0

對於Xml Serializer來說,您的類必須具有公共的無參數構造函數。 –

回答

1

當我讀到你的xml,你似乎想序列化一個Employee列表。 如果您的列表是類的成員(不是直接序列化列表),我有一個解決方案。

public abstract class Employee 
{ 
    public string Name { get; set; } 
    public int ID { get; set; } 
    public Employee(string Name, int ID) 
    { 
     this.Name = Name; 
     this.ID = ID; 
    } 
} 

public class HR : Employee 
{ 
    public HR() : base(null, 0) { } // default constructor is needed for serialization/deserialization 
    public HR(string Name, int ID) : base(Name, ID) { } 
} 
public class IT : Employee 
{ 
    public IT() : base(null, 0) { } 
    public IT(string Name, int ID) : base(Name, ID) { } 
} 

public class Group 
{ 
    [XmlArray("Employee")] 
    [XmlArrayItem("HR",typeof(HR))] 
    [XmlArrayItem("IT",typeof(IT))] 
    public List<Employee> list { get; set; } 

    public Group() 
    { 
     list = new List<Employee>(); 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Group grp = new Group(); 
     grp.list.Add(new HR("Name HR", 1)); 
     grp.list.Add(new IT("Name IT", 2)); 

     XmlSerializer ser = new XmlSerializer(typeof(Group)); 
     ser.Serialize(Console.Out, grp); 
    } 
} 

,輸出是:

<?xml version="1.0" encoding="ibm850"?> 
<Group xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Employee> 
    <HR> 
     <Name>Name HR</Name> 
     <ID>1</ID> 
    </HR> 
    <IT> 
     <Name>Name IT</Name> 
     <ID>2</ID> 
    </IT> 
    </Employee> 
</Group> 

非常相似,所需輸出,除外多了一個元素在根「本集團」。

使用相同的XmlSerializer(typeof(Group))反序列化也應該可以。

+0

非常感謝!這工作! :) – Sugan88

1

添加[Serializable接口]註釋您要序列化類。

 [System.Serializable] 
     public class Base 
     { 
     public string Name { get; set; } 
     public int ID { get; set; } 

     public Base(string Name, int ID) 
      { 
      this.Name = Name; 
      this.ID = ID; 
      } 
     } 

要序列化XML格式,使用下面的代碼:

 System.Xml.Serialization.XmlSerializer Serializer = new System.Xml.Serialization.XmlSerializer(typeof(Base)); 
     Base Foo = new Base(); 
     string xmldata = ""; 

     using (var stringwriter = new System.IO.StringWriter()) 
     { 
      using (System.Xml.XmlWriter xmlwriter = System.Xml.XmlWriter.Create(stringwriter)) 
      { 
       Serializer.Serialize(xmlwriter, Foo); 
       xml = stringwriter.ToString(); // Your XML 
      } 
     } 

從XML序列化回到你的基本對象,使用下面的代碼:

 System.IO.MemoryStream FooStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml)); 
     Base Foo; 
     Foo = (Base)Serializer.Deserialize(FooStream); 
+0

非常感謝! Employee Foo = new Employee()會拋出一個錯誤,因爲我認爲它不可能創建一個抽象類的實例? – Sugan88

+0

您需要在類中使用默認構造函數以使序列化程序工作並使用具體類型。 – mahlatse

+0

我很抱歉,我沒有先閱讀抽象部分,也無法創建抽象類的實例,爲true。但是你的問題固有地圍繞它的序列化來表示,你會有一個對象,上面的代碼很適合序列化創建的對象 –

1

我想你需要使用XmlType屬性來確保您的元素顯示爲<HR><IT>而不是<employee xsi:type="HR">。下面的工作演示:

public abstract class Employee 
{ 
    public string Name { get; set; } 
    public string ID { get; set; } 

    public Employee(string Name, string ID) 
    { 
     this.Name = Name; 
     this.ID = ID; 
    } 
} 

public class HR : Employee 
{ 
    public HR(string Name, string ID) : base(Name, ID) 
    { 
    } 


    public HR() : base("No name", "No ID") 
    { 

    } 
} 

public class IT : Employee 
{ 
    public IT(string Name, string ID) : base(Name, ID) 
    { 
    } 

    public IT() : base("No name", "No ID") 
    { 

    } 
} 

我添加了序列化程序的默認(無參數)構造函數。

然後,你必須有某種包裝對象來處理的Employee個清單:

public class Employees 
{ 
    [XmlElement(typeof(IT))] 
    [XmlElement(typeof(HR))] 
    public List<Employee> Employee { get; set; } //It doesn't really matter what this field is named, it takes the class name in the serialization 
} 

接下來,您可以使用串行代碼從我的評論生成XML:

var employees = new Employees 
{ 
    Employee = new List<Employee>() 
    { 
     new IT("Sugan", "88"), 
     new HR("Niels", "41") 
    } 
}; 

var serializer = new XmlSerializer(typeof(Employees)); 
var xml = ""; 

using (var sw = new StringWriter()) 
{ 
    using (XmlWriter writer = XmlWriter.Create(sw)) 
    { 
     serializer.Serialize(writer, employees); 
     xml = sw.ToString(); 
    } 
} 
Console.WriteLine(xml); 

(ommitted爲清楚起見命名空間)

這將返回以下XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Employees xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <IT> 
     <Name>Sugan</Name> 
     <ID>88</ID> 
    </IT> 
    <HR> 
     <Name>Niels</Name> 
     <ID>41</ID> 
    </HR> 
</Employees> 
+0

您可以找到避免解決方案中額外級別的方法,謝謝。 – Pascal

+0

非常感謝!你的解決方案也能工作但我只能將其中一個標記爲「已回答」 – Sugan88