XmlSerializer Deserializing Array/List of Multiple Objects at Root

Brian Chavez picture Brian Chavez · Dec 22, 2009 · Viewed 15.6k times · Source

I'm trying to deserialize the following XML output:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Foo>
   <Val>Data1</Val>
</Foo>
<Foo>
   <Val>Data2</Val>
</Foo>

(This is output from a hardware device, and cannot be changed)

I have an XML type defined as:

    [XmlType(AnonymousType=true, Namespace="")]
    public class Foo
    {
        public string Val { get; set; }
    }

I've tried to deserialize this array by creating a serializer like:

  var s = new XmlSerializer(typeof(Foo[]));
  //or
  var s = new XmlSerializer(typeof(List<Foo>);

But every call to s.Deserialize() causes an InvalidOperaitonException:

 System.InvalidOperationException: <Foo xmlns=''> was not expected.

Note

 var s = new XmlSerializer(typeof(Foo));
 // Only deseralizes the first Foo (Data1).

Thanks for your help.

Answer

Adriaan Stander picture Adriaan Stander · Dec 22, 2009

I think the issue is with your provided xml.

Test app says

List<Foo> list = new List<Foo> {new Foo {Val = "Data1"}, new Foo {Val = "Data2"}};
var s = new XmlSerializer(typeof(List<Foo>));
StringBuilder sb = new StringBuilder();
XmlWriter wr = XmlWriter.Create(sb);
s.Serialize(wr, list);

string ss = sb.ToString();

var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr);

And the XML should be

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfFoo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Foo>
        <Val>Data1</Val>
    </Foo>
    <Foo>
        <Val>Data2</Val>
    </Foo>
</ArrayOfFoo>

If you can remove the inital line

<?xml version="1.0" encoding="ISO-8859-1"?>

And minipulate the string into

string s = "<ArrayOfFoo><Foo>   <Val>Data1</Val></Foo><Foo>   <Val>Data2</Val></Foo></ArrayOfFoo>";
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(s);
List<Foo> list = (List<Foo>)s2.Deserialize(sr);

That could work.