XMLSerializer stores items in a collection

I need to export a collection of objects to the camel shell, for this I use a wrapper.

The class itself:

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

This serializes perfectly:

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

Wrapper:

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

This, however, capitalizes the wrapped Example for some reason, I tried to override it with an XmlElement , but this does not seem to have the desired effect:

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

Who can tell me what I'm doing wrong, or if there is an easier way?

+6
source share
2 answers

The problem is that the XmlSerializer has built-in collection type handling, i.e. it ignores all your properties and fields (including innerList ) if your type implements ICollection and will just serialize it according to its own rules. However, you can configure the name of the element that it uses for collection elements with the XmlType attribute (unlike the XmlRoot that you used in your example):

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

This will have the desired serialization.

See http://msdn.microsoft.com/en-us/library/ms950721.aspx , in particular the answer to the question "Why aren’t all the properties of the collection classes serialized?"

+5
source

Unfortunately, you cannot only use attributes to make this happen. You also need to use attribute overrides. Using the classes above, I can use XmlTypeAttribute to override the string representation of the class.

 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()); } 

This gives

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

which I think you need.

0
source

All Articles