2011-12-15 37 views
2

私はオブジェクトの2つの異なるバージョンでデータを保存しようとしていて、それに成功しません。誰かが私が間違っていることを教えてもらえますか?[XmlAnyElement]を使用する

版クラスの一つ:

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

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

    [XmlAnyElement] 
    public XmlElement[] XElements; 
} 

版クラスの2つの物体の

[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:V1オブジェクトにオブジェクトの

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。 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); 
} 
+0

私はそれを全く見ないと思っています。 –

+0

なぜですか?私は、[XmlAnyElement]は、オブジェクトの一部ではないXMLファイル内のデータのキャッチオールであると考えました。私はここから完全に離れていますか? –

+0

それは配列なので、XElememtsタグに含まれます。それ以外の選択肢は、XElments内に年齢、名前、体重があった場合、個々のプロパティを上書きすることを意味します。 tahtを避けることは、KISSの原則を真剣に破ります。 –

答えて

1

を発生しませんXml*AttributeクラスがないDataContractSerializerにより、XmlSerializerで使用されています。私が知る限り、DataContractSerializerにはこのシナリオを処理する仕組みがありません。可能であれば、代わりにXmlSerializerを使用してください。これははるかに柔軟です。

0

アプリケーションの要件である場合は、OnDeserializing属性で装飾されたメソッドを追加し、独自のロジックを実装して、XmlElementコレクションに不足するフィールドを追加することができます。

1

DataContract秒の未来や過去のバージョンの未知の要素を保持するために、あなたはIExtensibleDataObjectインターフェイスを実装することができます。そうすることで未知の要素がExtensionDataというプロパティに配置され、データの欠落なく将来の再直列化が可能になります。

使用例は以下のようになり:Person_V2オブジェクトがPerson_V1オブジェクトに逆シリアル化されるとき

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

WeightプロパティはExtensionDataに格納され、それが再直列化されたときにシリアライズストリームに戻されます。

関連する問題