2016-09-22 4 views
0

Мне нужно выполнить очень простую задачу: сериализовать и десериализовать иерархию объектов.C# serializer/deserializer с такой же функциональностью, как XStream в java

Я пробовал XMLSerializer, DataContractSerializer, NetDataContractSerializer, но ничего не работает, всегда есть проблема.

XMLSerializer плохо, потому что для этого требуются все свойства. (Net) 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# ВЫ ИСПОЛЬЗУЕТЕ НЕДВИЖИМОСТЬ !! –

ответ

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 
    { 
    } 

Read

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, который имеет такой же интерфейс, как С. Вместо Список , может быть там List так что пользователь может сделать что-то вроде: <...> ? –

+0

Да, вы могли бы создать пользовательский [DataContractResolver] (https://msdn.microsoft.com/en-us/library/ee358759%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). Не забудьте пометить его как ответ, если это все, что вам нужно. –

+0

Возможно, вам захочется взглянуть на XElement и XDocument, которые они очень хорошо используют и позволят вам полностью контролировать создание объектов. –