使用[XmlAnyElement]

时间:2011-12-15 12:37:42

标签: c# xml-serialization

我正在尝试保留对象的两个不同版本的数据,并且没有取得任何成功。谁能告诉我我做错了什么?

班级版本之一:

 [DataContract (Name="Person")]
 public class Person_V1
 {
     [DataMember(Name = "Name")]
     public string Name;

     [DataMember(Name = "Age")]
     public int Age;

     [XmlAnyElement]
     public XmlElement[] XElements;
}

班级第二版:

[DataContract(Name = "Person")]
public class Person_V2
{
    [DataMember(Name = "Name")]
    public string Name;

    [DataMember(Name = "Age")]
    public int Age;

    [DataMember(Name = "Weight")]
    public int Weight;

    [XmlAnyElement]
    public XmlElement[] XElements;
}

保存对象的V2:

private void btnSave_V2_Click(object sender, EventArgs e)
{
    Person_V2 p = new Person_V2() { Name = "Carrie", Age = 31, Weight = 125 };

    var ds = new DataContractSerializer(typeof(Person_V2));

    XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };

    using (XmlWriter w = XmlWriter.Create("person.xml", settings))
        ds.WriteObject(w, p);
}

将对象的V2恢复为V1对象。期望看到XElements数组中保存的权重变量信息,但它不会发生

private void btnRestore_V1_Click(object sender, EventArgs e)
{
    Person_V1 p;

    var ds = new DataContractSerializer(typeof(Person_V1));

    XmlReaderSettings settings = new XmlReaderSettings();

    using (XmlReader r = XmlReader.Create("person.xml", settings))
        p = (Person_V1)ds.ReadObject(r);

    MessageBox.Show(p.Name + " " + p.Age);
}

3 个答案:

答案 0 :(得分:1)

Xml*Attribute类由XmlSerializer使用,而不是DataContractSerializer。据我所知,DataContractSerializer没有任何机制来处理这种情况。如果可以,请改用XmlSerializer,它会更加灵活。

答案 1 :(得分:1)

要保留DataContract的未来或过去版本的未知元素,您可以实现IExtensibleDataObject接口。这样做会导致任何未知元素被放置在名为ExtensionData的属性中,这允许将来重新序列化而不会丢失数据。

示例用法是:

[DataContract(Name="Person")]
public class Person_V1 : IExtensibleDataObject
{
    [DataMember(Name = "Name")]
    public string Name;

    [DataMember(Name = "Age")]
    public int Age;

    public ExtensionDataObject ExtensionData { get; set; }
}

Person_V2对象反序列化为Person_V1对象时,Weight属性存储在ExtensionData中,并在重新生成时返回到序列化流序列

答案 2 :(得分:0)

如果这是您的应用程序的要求,您可以添加一个用OnDeserializing属性修饰的方法,然后实现您自己的逻辑以将缺少的字段添加到XmlElement集合。