2016-09-22 19 views
0

我需要完成非常简单的任务:序列化和反序列化对象层次结构。与java中的XStream具有相同功能的C#序列化器/解串器

我试过XMLSerializer,DataContractSerializer,NetDataContractSerializer但似乎没有任何工作,总会有一些问题。

XMLSerializer是不好的,因为它需要所有的属性公开。 (网络)DataContractSerializer(s)不好,因为它总是缺少一些元数据 - 但在用户创建XML时没有元数据。

那么你将如何解决这个任务?考虑类:

class A { 
    private B instanceB; 
    private int integerValue; 

    ... getters/setters 
} 

class B { 
    private List<C> cInstanceList; 
    private string stringValue; 
    ... getters/setters 
} 

class C { 
    ... some other properties 
    ... getters/setters 
} 

和用户输入:

<A> 
    <B> 
    <cInstanceList> 
     <C> 
     <someproperties>val</someproperties> 
     </C> 
     <C> 
     <someproperties>differentVal</someproperties> 
     </C> 
    </cInstanceList> 
    <strigValue>lalala<stirngValue> 
    </B> 
    <integerValue>42</integerValue> 
</A> 

什么DataContractors缺少的是像 “类型” 或 “命名空间” 等XStream不需要的元数据。我知道反序列化对象的类型,所以我需要写功能:

public T Deserialize<T>(string xml); 

我想要的用例:

var myDeserializedObject = Deserialize<A>(inputString); 

我在做什么错?你会以不同的方式解决吗?

+0

噢,我忘了你不要在C#中使用getter和setter你使用属性! –

回答

1

没有序列化程序将修复打字错误;)。这种使用的DataContractSerializer XML(text.xml)

<A> 
    <B> 
    <cInstanceList> 
     <C> 

     </C> 
     <C> 
     </C> 
    </cInstanceList> 
    <stringValue>lalala</stringValue> 
    </B> 
    <integerValue>42</integerValue> 
</A> 

[DataContract(Namespace="")] 
    class A 
    { 
     [DataMember(Name = "B")] 
     private B instanceB; 
     [DataMember(Name = "integerValue")] 
     private int integerValue; 

     public A(B instanceB, int integerValue) 
     { 
      this.instanceB = instanceB; 
      this.integerValue = integerValue; 
     } 
    } 

    [DataContract(Namespace = "")] 
    class B 
    { 
     [DataMember(Name = "cInstanceList")] 
     private List<C> cInstanceList; 

     [DataMember(Name = "stringValue")] 
     private string stringValue; 

     public B(List<C> cInstanceList, string stringValue) 
     { 
      this.cInstanceList = cInstanceList; 
      this.stringValue = stringValue; 
     } 
    } 

    [DataContract(Namespace = "")] 
    class C 
    { 
    } 

工作,我读

var dcs = new DataContractSerializer(typeof(A)); 
using (Stream reader = File.OpenRead("text.xml")) 
{ 
    var result = (A)dcs.ReadObject(reader); 
} 

如果你把它写将添加的xmlns:I =“HTTP: //www.w3.org/2001/XMLSchema-instance“,但如果您真的需要,可以将其删除。

+0

不错!有没有可能有界面? 考虑类d具有相同的接口C.不是List 的,可能是有名单,以便用户可以这样做: <...> ? –

+0

是的,您可以通过自定义[DataContractResolver](https://msdn.microsoft.com/en-us/library/ee358759%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)。如果你需要这一切,不要忘记把它作为回答。 –

+0

O你可能想看看XElement和XDocument,它们使用起来非常好,并且可以完全控制对象的创建。 –

相关问题