2013-01-03 14 views
6

Potrzebuję wyeksportować kolekcję przedmiotów w obudowie wielbłąda, do tego używam otoki.XMLSerializer przechowuje duże elementy w kolekcji

Klasa sama w sobie:

[XmlRoot("example")] 
public class Example 
{ 
    [XmlElement("exampleText")] 
    public string ExampleText { get; set; } 
} 

Ten serializes porządku:

<example> 
    <exampleText>Some text</exampleText> 
</example> 

Opakowanie:

[XmlRoot("examples")] 
public class ExampleWrapper : ICollection<Example> 
{ 
    [XmlElement("example")] 
    public List<Example> innerList; 

    //Implementation of ICollection using innerList 
} 

to jednak czerpie zawiniętego Example s jakiegoś powodu, próbowałem zastąpić go XmlElement, ale nie wydaje się, że ma pożądany effe ct:

<examples> 
    <Example> 
     <exampleText>Some text</exampleText> 
    </Example> 
    <Example> 
     <exampleText>Another text</exampleText> 
    </Example> 
</examples> 

Kto może mi powiedzieć, co robię źle lub czy jest łatwiejszy sposób?

+0

Zawsze możesz zmienić nazwę typu "Przykład" na "przykład" jako obszar roboczy ... Jeśli możesz znieść łamanie konwencji ... – RichardTowers

Odpowiedz

5

Problemem jest to, że XmlSerializer ma wbudowaną obsługę dla typów kolekcji, co oznacza, że ​​będzie ona ignorować wszystkie swoje właściwości i pól (w tym innerList) Jeśli typ stanie wdrożyć ICollection i będzie tylko szeregować je zgodnie z własnymi zasadami. Można jednak dostosować nazwę elementu to wykorzystuje do zbierania przedmiotów z atrybutem XmlType (w przeciwieństwie do XmlRoot że użył w swoim przykładzie):

[XmlType("example")] 
public class Example 
{ 
    [XmlElement("exampleText")] 
    public string ExampleText { get; set; } 
} 

który będzie miał pożądaną serializacji.

Zobacz http://msdn.microsoft.com/en-us/library/ms950721.aspx, w szczególności odpowiedź na pytanie "Dlaczego nie wszystkie właściwości klas kolekcji są serializowane?"

+0

Masz rację! Dzięki. Odrzuciłem implementację 'ICollection' na rzecz dziedziczenia z' List'. Wygląda na to, że 'XmlRoot' nie jest potrzebny, czy mam rację? – siebz0r

+0

Prawidłowo, 'XmlRoot' będzie konieczne tylko na' Przykładie', jeśli używasz tego jako katalogu głównego wykresu z serializowanym obiektem. – luksan

0

Niestety, nie można użyć tylko atrybutów, aby tak się stało. Musisz także użyć zastąpień atrybutów. Używając was z klas powyżej, mogę użyć XmlTypeAttribute, aby nadpisać reprezentację łańcuchową klasy.

var wrapper = new ExampleWrapper(); 
var textes = new[] { "Hello, Curtis", "Good-bye, Curtis" }; 
foreach(var s in textes) 
{ 
    wrapper.Add(new Example { ExampleText = s }); 
} 

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
XmlAttributes attributes = new XmlAttributes(); 
XmlTypeAttribute typeAttr = new XmlTypeAttribute(); 
typeAttr.TypeName = "example"; 
attributes.XmlType = typeAttr; 
overrides.Add(typeof(Example), attributes); 

XmlSerializer serializer = new XmlSerializer(typeof(ExampleWrapper), overrides); 
using(System.IO.StringWriter writer = new System.IO.StringWriter()) 
{ 
    serializer.Serialize(writer, wrapper); 
    Console.WriteLine(writer.GetStringBuilder().ToString()); 
} 

Daje

<examples> 
    <example> 
    <exampleText>Hello, Curtis</exampleText> 
    </example> 
    <example> 
    <exampleText>Good-bye, Curtis</exampleText> 
    </example> 
</examples> 

które wierzę chciałeś.

Powiązane problemy