2017-01-25 2 views
4

Я хочу сериализации и десериализации объекта, как это:C# XML тип Сериализация IXmlSerializable

public class Root 
{ 
    public string title; 
    [XmlArray("lista")] 
    [XmlArrayItem("Parameter")] 
    public List<Parameter> lista; 
} 

public class Parameter : IXmlSerializable 
{ 
    public string name; 
    public int val; 

    public void WriteXml(XmlWriter writer) 
    { 
     writer.WriteElementString("name",name); 
     writer.WriteElementString("val",val.ToString()); 
    } 

    public void ReadXml(XmlReader reader) 
    {   
     reader.ReadToDescendant("name"); 
     name = reader.ReadElementContentAsString(); 
     val = reader.ReadElementContentAsInt(); 
    } 

    public XmlSchema GetSchema() 
    { 
     return (null); 
    } 
} 

Проблема заключается в том, что когда я десериализации этот объект, он добавляется только первый элемент списка. Пример:

Сериализованная:

<Root> 
<title>title</title> 
<lista> 
<Parameter> 
    <name>pa</name> 
    <val>1</val> 
</Parameter> 
<Parameter> 
    <name>pb</name> 
    <val>2</val> 
</Parameter> 
</lista> 
</Root> 

Десериализованный:

<Root> 
<title>title</title> 
<lista> 
<Parameter> 
    <name>pa</name> 
    <val>1</val> 
</Parameter> 
</lista> 
</Root> 

Я реализовал Fiddle пример. Может кто-нибудь мне помочь?

+0

Есть ли особая причина, почему вы используете собственный сериализатор? Вышеупомянутое не нуждается в этом. –

+0

@TimRutter Это, вероятно, SSCCE, лучше, чем публикация класса 500 строк – Sentry

+0

@ Sentry. Достаточно, но стоит спросить. Думаю –

ответ

4

Вы просто читаете первый элемент вам следует добавить reader.Read(); в конце метода RealXml создать цикл:

public void ReadXml(XmlReader reader) 
{ 
    reader.ReadToDescendant("name"); 
    name = reader.ReadElementContentAsString(); 
    val = reader.ReadElementContentAsInt(); 
    reader.Read(); 
} 

, но вам не нужно осуществлять IXmlSerializable, если у вас нет конкретной причина для этого. вы могли бы просто использовать XmlSerializer, как показано ниже:

XmlSerializer serializer = new XmlSerializer(typeof(Root)); 
StringBuilder result = new StringBuilder(); 
using (var writer = XmlWriter.Create(result)) 
{ 
    serializer.Serialize(writer, root); /// serialize    
} 

using (var reader = new StringReader(result.ToString())) 
{ 
    var deserialized = (Root)serializer.Deserialize(reader); //// deserialize from string 
} 
+0

Большое спасибо! Я использую IXmlSerializable, потому что в реальном коде класс «Параметр» имеет переменную типа «System.Object» –

0

Если вы не должны использовать изменяющийся класс параметров пользовательского сериалайзер на следующем решает проблему (протестировано в вашей скрипке примера):

public class Parameter 
{ 
    public string name {get;set;} 
    public int val {get;set;} 

} 
Смежные вопросы