Search code examples
c#xmldatacontractserializer

How to deserialize Xml with root than multiple child elements of the same type


I'm trying deserialize a xml document that looks like this

<invoices>
  <invoice>2848</invoice>
  <invoice>2849</invoice>
  <invoice>2850</invoice>
  <invoice>2851</invoice>
  <invoice>2852</invoice>
</invoices>

Into a C# object, but I cannot get it to work. I'm using the DataContractSerializer

This is what my class looks like:

[DataContract(Name = "invoices", Namespace = "")]
public class Invoices
{
    [DataMember(Name = "invoice")]
    public Invoice[] InvoiceIds { get; set; }
}

[DataContract(Name = "invoice", Namespace = "")]
public class Invoice
{
    [DataMember(Name = "invoice")]
    public string Id { get; set; }
}

Of course this does not work. I get this error:

{"Error in line 1 position 24. Expecting state 'Element'.. Encountered 'Text'  with name '', namespace ''. "}

I'm not in control of the Xml.


Solution

  • Try using a [CollectionDataContract] for this scenario:

    public class StackOverflow_10705733
    {
        [CollectionDataContract(Name = "invoices", ItemName = "invoice", Namespace = "")]
        public class Invoices : List<int>
        {
            [DataMember(Name = "invoice")]
            public int[] InvoiceIds { get; set; }
        }
        public static void Test()
        {
            DataContractSerializer dcs = new DataContractSerializer(typeof(Invoices));
            string xml = @"<invoices>
                              <invoice>2848</invoice>
                              <invoice>2849</invoice>
                              <invoice>2850</invoice>
                              <invoice>2851</invoice>
                              <invoice>2852</invoice>
                            </invoices>";
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
            Invoices value = dcs.ReadObject(ms) as Invoices;
            Console.WriteLine(string.Join(",", value));
        }
    }