繁体   English   中英

c#中类集合的XML序列化

[英]XML Serialization of class collection in c#

我有一个包含对象集合的类。 集合中的对象是同一类的后代。 A类是基类,B类和C类继承自A类.B和C各有一些不同的成员。 该系列是LIst系列。

我想序列化包含该集合的类。 如何将不同的类归因于能够序列化和反序列化xml文件?

谢谢,罗伯特

[Serializable]属性与XML序列化无关。 XML序列化程序使用public getter AND setter序列化属性。 此外,您必须通过将Type[]额外参数传递给序列化程序ctor或添加[XmlInclude(typeof(B))] ,告诉XML序列化程序它可以使用的额外类型,静态不知道的Type[][XmlInclude(typeof(C))]

编辑:

以下代码:

[XmlInclude(typeof(B))]
[XmlInclude(typeof(C))]
public class A
{
    public int Value;
    public A() { }
    public A(int i) { Value = i; }
}

public class B : A
{
    public double DoubleValue;
    public B() { }
    public B(int i, double d) : base(i) { DoubleValue = d; }
}

public class C : A
{
    public string StringValue;
    public C() { }
    public C(int i, string s) : base(i) { StringValue = s; }
}

public class Container
{
    public List<A> Items;
    public Container()
    {
        Items = new List<A>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Container container = new Container();
        container.Items.Add(new B(0, 1.3d));
        container.Items.Add(new B(1, 0.37d));
        container.Items.Add(new C(2, "c"));

        using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"C:\TEMP\Container.xml"))
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Container));
            serializer.Serialize(writer, container);
        }
    }
}

生成那个xml:

<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <A xsi:type="B">
      <Value>0</Value>
      <DoubleValue>1.3</DoubleValue>
    </A>
    <A xsi:type="B">
      <Value>1</Value>
      <DoubleValue>0.37</DoubleValue>
    </A>
    <A xsi:type="C">
      <Value>2</Value>
      <StringValue>c</StringValue>
    </A>
  </Items>
</Container>

您可以使用XmlSerialization或DataContract(或更“原始”实现),请参阅: http//www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in -wcf /

至于序列化:您只需要标记要序列化的类,因此您需要标记B类和C类,但不需要标记A类。

但是我建议你将A类标记为可序列化,因此让你和其他程序员更清楚这个类支持序列化。

您不需要将类属性设置为使用Xml序列化:

using System;
using System.IO;
using System.Xml.Serialization;

/* Three classes are included here. Each one will
be used to create three XmlSerializer objects. */

public class Instrument
{
   public string InstrumentName;
}

public class Player
{
   public string PlayerName;
}

public class Piece
{
   public string PieceName;
}

public class Test
{
   public static void Main()
   {
      Test t = new Test();
      t.GetSerializers();
   }

   public void GetSerializers()
   {
      // Create an array of types.
      Type[]types = new Type[3];
      types[0] = typeof(Instrument);
      types[1] = typeof(Player);
      types[2] = typeof(Piece);

      // Create an array for XmlSerializer objects.
      XmlSerializer[]serializers= new XmlSerializer[3];
      serializers = XmlSerializer.FromTypes(types);
      // Create one Instrument and serialize it.
      Instrument i = new Instrument();
      i.InstrumentName = "Piano";
      // Create a TextWriter to write with.
      TextWriter writer = new StreamWriter("Inst.xml");
      serializers[0].Serialize(writer,i);
      writer.Close();
   }
}

要使用集合,可以按如下方式对其进行序列化:

using System;
using System.IO;
using System.Collections;
using System.Xml.Serialization;

public class Test{
    static void Main(){
        Test t = new Test();
        t.SerializeCollection("coll.xml");
    }

    private void SerializeCollection(string filename){
        Employees Emps = new Employees();
        // Note that only the collection is serialized -- not the 
        // CollectionName or any other public property of the class.
        Emps.CollectionName = "Employees";
        Employee John100 = new Employee("John", "100xxx");
        Emps.Add(John100);
        XmlSerializer x = new XmlSerializer(typeof(Employees));
        TextWriter writer = new StreamWriter(filename);
        x.Serialize(writer, Emps);
    }
}
public class Employees:ICollection{
    public string CollectionName;
    private ArrayList empArray = new ArrayList(); 

    public Employee this[int index]{
        get{return (Employee) empArray[index];}
    }

    public void CopyTo(Array a, int index){
        empArray.CopyTo(a, index);
    }
    public int Count{
        get{return empArray.Count;}
    }
    public object SyncRoot{
        get{return this;}
    }
    public bool IsSynchronized{
        get{return false;}
    }
    public IEnumerator GetEnumerator(){
        return empArray.GetEnumerator();
    }

    public void Add(Employee newEmployee){
        empArray.Add(newEmployee);
    }
}

public class Employee{
    public string EmpName;
    public string EmpID;
    public Employee(){}
    public Employee(string empName, string empID){
        EmpName = empName;
        EmpID = empID;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM