siebz0r
siebz0r

Reputation: 20359

XMLSerializer keeps capitalizing items in collection

I need to export a collection of items in camel casing, for this I use a wrapper.

The class itself:

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

This serializes fine:

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

The wrapper:

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

    //Implementation of ICollection using innerList
}

This however capitalizes the wrapped Examples for some reason, I tried to override it with XmlElement but this doesn't 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 am doing wrong or if there is an easier way?

Upvotes: 7

Views: 1042

Answers (3)

Chathu.Thanthrige
Chathu.Thanthrige

Reputation: 133

[xmlType("DISPLAY_NAME")] is working for Inner object naming in xml Serialization in collections

 [XmlType("SUBSCRIPTION")]
    public class Subscription
    {

Upvotes: 0

luksan
luksan

Reputation: 7767

The problem is that XmlSerializer has built-in handling for collection types, meaning it it will ignore all your properties and fields (including innerList) if your type happens to implement ICollection and will just serialize it according to its own rules. However, you can customize the name of the element it uses for the collection items with the XmlType attribute (as opposed to the XmlRoot that you had used in your example):

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

That will have the desired serialization.

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

Upvotes: 5

realistschuckle
realistschuckle

Reputation: 580

Unfortunately, you cannot use just attributes to make this happen. You need to also use attribute overrides. Using you classes from above, I can use the 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 believe you wanted.

Upvotes: 0

Related Questions