2016-04-08 6 views
0

Personから派生したStudentクラスとEmployeeクラスに対して次のコードを使用しています。XMLシリアライゼーションは、XSIでDerviedクラス名をオーバーライドします。タイプ

[XmlInclude(typeof(Student)), XmlInclude(typeof(Employee))] 
public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public string Gender { get; set; } 
} 

[XmlType("Student")] 
public class Student : Person 
{ 
    public int StudentId { get; set; } 
    public List<string> Subjects { get; set; } 
} 

[XmlType("Employee")] 
public class Employee : Person 
{ 
    public int EmployeeId { get; set; } 
    public float Experience { get; set; } 
} 

私はPersonクラスのリストを作成しており、次の値で初期化し、同じものをシリアル化してXMLを生成します。

public class TestSerialization 
{   
    List<Person> lstPerson = new List<Person>(); 

    public void XMLGen() 
    { 

     Person obj = new Person() { Name = "Person1", Age = 10, Gender = "M" }; 
     Person obj2 = new Person() { Name = "Person2", Age = 10, Gender = "F" }; 

     Student objS = new Student() 
     { 
      Name = "Student1", 
      Age = 20, 
      Gender = "M", 
      StudentId = 1, 
      Subjects = new List<string>() { "Math", "Science" } 
     }; 
     Student objS2 = new Student() 
     { 
      Name = "Student2", 
      Age = 15, 
      Gender = "F", 
      StudentId = 1, 
      Subjects = new List<string>() { "Physics", "Chemistry" } 
     }; 

     Employee objE = new Employee() 
     { 
      Name = "Employee1", 
      Age = 15, 
      Gender = "F", 
      EmployeeId = 1, 
      Experience = 5.5f 
     }; 

     Employee objE2 = new Employee() 
     { 
      Name = "Employee2", 
      Age = 15, 
      Gender = "M", 
      EmployeeId = 2, 
      Experience = 6.5f 
     }; 

     lstPerson.Add(obj); 
     lstPerson.Add(obj2); 
     lstPerson.Add(objS); 
     lstPerson.Add(objS2); 
     lstPerson.Add(objE); 
     lstPerson.Add(objE2); 

     Type[] types = { typeof(Student), typeof(Employee) }; 

     XmlSerializer objXml = new XmlSerializer(typeof(List<Person>), types); 

     using (StringWriter textWriter = new StringWriter()) 
     { 
      objXml.Serialize(textWriter, lstPerson); 
      string aa = textWriter.ToString(); 
     } 

    } 

} 

しかし、XSIとして派生クラス名が含まれて生成されたXML:タイプ=「学生」とXSI:種類は=「従業員」を下記のように。タイプ:

<Person xsi:type="Student"> 
<Name>Student1</Name> 
<Age>20</Age> 
<Gender>M</Gender> 
<StudentId>1</StudentId> 
<Subjects> 
    <string>Math</string> 
    <string>Science</string> 
</Subjects> 

と従業員のために、それは

<Person xsi:type="Employee"> 
<Name>Employee2</Name> 
<Age>15</Age> 
<Gender>M</Gender> 
<EmployeeId>2</EmployeeId> 
<Experience>6.5</Experience> 

であることは、それは我々がXSIと学生、従業員ではなく、人としてXMLノード名を取得することは可能ですか?

私はこのようなXMLが必要です。あなたは再びXMLから読み取るしようとすると、

<Employee> 
<Name>Employee2</Name> 
<Age>15</Age> 
<Gender>M</Gender> 
<EmployeeId>2</EmployeeId> 
<Experience>6.5</Experience> 

答えて

0

xsi:typeは、逆シリアル化のために必要とされます。それ以外の場合、デシリアライザは、どのクラスを非直列化するかを知らないでしょう。

クラスに再度デシリアライズする予定がない場合は、独自のカスタムシリアライザを追加できます。

+0

同じ結果が得られます。

+0

私は以前これをやったと思いましたが、それは別のシナリオでした。私の答えは更新されました。 –

0

xmlrootを追加すると、ルートタグがemployeeとして指定されます。クラス構造の継承のためにtype属性を削除することはできません。

[XmlInclude(typeof(Student)), XmlInclude(typeof(Employee))] 
    [XmlRoot("Employee")] 
    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
     public string Gender { get; set; } 
    } 

    [XmlType("Student")] 
    public class Student : Person 
    { 
     public int StudentId { get; set; } 
     public List<string> Subjects { get; set; } 
    } 

    [XmlType("Employee")] 
    public class Employee : Person 
    { 
     public int EmployeeId { get; set; } 
     public float Experience { get; set; } 
    } 
0

私はhttps://msdn.microsoft.com/en-us/library/3z3z5s6h%28v=vs.110%29.aspxリンクから解決策を得ました。 XmlElementAttributeを使用して要素名を変更し、XmlElementAttributeをXmlAttributesインスタンスに追加します。次に、XmlAttributeをXmlAttributeOverridesインスタンスに追加し、オーバーライドされる型と派生クラスを受け入れるメンバの名前を指定します。

public class Orders 
{ 
    public List<Person> Persons; 
} 

public void SerializeObject(string filename) 
    { 
     // Each overridden field, property, or type requires 
     // an XmlAttributes instance. 
     XmlAttributes attrs = new XmlAttributes(); 

     // Creates an XmlElementAttribute instance to override the 
     // field that returns Book objects. The overridden field 
     // returns Expanded objects instead. 
     XmlElementAttribute attr = new XmlElementAttribute(); 
     attr.ElementName = "Student"; 
     attr.Type = typeof(Student); 

     XmlElementAttribute attrE = new XmlElementAttribute(); 
     attrE.ElementName = "Employee"; 
     attrE.Type = typeof(Employee); 

     // Adds the element to the collection of elements. 
     attrs.XmlElements.Add(attr); 
     attrs.XmlElements.Add(attrE); 

     // Creates the XmlAttributeOverrides instance. 
     XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); 

     // Adds the type of the class that contains the overridden 
     // member, as well as the XmlAttributes instance to override it 
     // with, to the XmlAttributeOverrides. 
     attrOverrides.Add(typeof(Orders), "Persons", attrs); 

     // Creates the XmlSerializer using the XmlAttributeOverrides. 
     XmlSerializer s = 
     new XmlSerializer(typeof(Orders), attrOverrides); 

シリアライズ時に、オーバーライド属性を使用してそのプロパティを上書きします。

関連する問題