1

Trying to deserialize List. Im getting the following error:

System.InvalidOperationException: There is an error in XML document (1, 2). ---> System.InvalidOperationException: was not expected.

Saw other quesitons like : {"<user xmlns=''> was not expected.} Deserializing Twitter XML but this does not solve my problem either.

This is an Xml Sample

<authorizations>
  <id>111</id>
  <name>Name 1</name>
  <Lists>
    <List>
      <id>1</id>
      <id>2</id>
    </List>
  </Lists>
</authorizations>
<authorizations>
  <id>222</id>
  <name>Name 2</name>
  <List />
</authorizations>
<authorizations>
  <id>333</id>
  <name>Name 3</name>
  <List />
</authorizations>

The class are created as follow:

    public class Authorization
    {
        [XmlElement("id")]
        public string Id{ get; set; }
        [XmlElement("name")]
        public string Name{ get; set; }
        [XmlArray("Lists")]
        [XmlArrayItem("List")]
        public List[] Items{ get; set; }
    }

    public class List
    {
        [XmlElement("id")]
        public string Id{ get; set; }
    }

    public class AuthorizationList
    {
        [XmlArray("authorizations")]
        public Authorization Authorizations{ get; set; }
    }

Have tried changing the list to XmlArray, XmlArrayItem or Element. but still get the same error when I deserialize.

Deserializing Code Sample:

    public static T FromXml<T>(string xmlString)
    {
        T obj = default(T);

        if (!string.IsNullOrWhiteSpace(xmlString))
        {
            using (var stringReader = new StringReader(xmlString))
            {
                var xmlSerializer = new XmlSerializer(typeof(T));

                obj = (T)xmlSerializer.Deserialize(stringReader);
            }
        }

        return obj;
    }
Community
  • 1
  • 1
RSmart
  • 13
  • 3
  • This is not a *valid* (expected by `XmlSerializer`) xml. Valid one begins from ``. You can try to add this line prior calling `Deserialize()`. Another thing is missing container (denoted by `XmlRootAttribute`) for array items, see e.g. [this](http://stackoverflow.com/q/126155/1997232). – Sinatr Aug 05 '16 at 15:03
  • `XmlSerializer` can process XML that is lacking an XML declaration. However, the XML must have one and only one [root element](https://en.wikipedia.org/wiki/Root_element). This XML has multiple root elements, so isn't really XML at all. – dbc Aug 05 '16 at 15:12
  • Gonna try adding a root element and let you know. Thanks for the fast responses – RSmart Aug 05 '16 at 15:20
  • If your "XML" really lacks a single root element, take a look at [XML parser, multipule roots](https://stackoverflow.com/questions/7199047/xml-parser-multipule-roots) or [C# XDocument Load with multiple roots](https://stackoverflow.com/questions/18186225) or [There are multiple root elements load xml](https://stackoverflow.com/questions/11644556). – dbc Aug 05 '16 at 15:22
  • Adding a root element to the XML solved the error. But now the de serializing returns 0 count, still verifying. – RSmart Aug 05 '16 at 15:41

1 Answers1

1

This is ALL premised on the assumption that you have minimal control over the xml and don't have the luxury of changing that too much. As others have noted, it is not well-formed. Here is one way to get serialization to work with minimal changes to your XML and types. First, get rid of your AuthorizationList type and assign an XmlType attribute to your Authorization type (this step serves to simply pluralize the name to match how your XML has it).

[XmlType("authorizations")]
public class Authorization { ... }

public class List { ... }

Wrap your XML in the following root element:

<ArrayOfAuthorizations>
...
</ArrayOfAuthorizations>

The XML now represents a list of "authorizations" so to deserialize is just this:

List<Authorization> l = FromXml<List<Authorization>>(xml);

Another Solution:

Change the Authorizations member to be of type Authorization[] (array type rather than singular) and to have an XmlElement attribute (not XmlArray). Apply the XmlType attribute to the Authorization (as with the above solution this is to match the xml since it has the pluralized name for each array element).

[XmlType("authorizations")]
public class Authorization
{
    [XmlElement("id")]
    public string Id { get; set; }
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlArray("Lists")]
    [XmlArrayItem("List")]
    public List[] Items { get; set; }
}

public class List
{
    [XmlElement("id")]
    public string Id { get; set; }
}

public class AuthorizationList
{
    [XmlElement("authorizations")]
    public Authorization[] Authorizations { get; set; }
}

Like before, you need to wrap your XML with the matching 'AuthorizationList' root element:

<AuthorizationList>
...
</AuthorizationList>

Then you deserialize instance of your AuthorizationList type rather that List<T> as with the previous solution.

AuthorizationList l = FromXml<AuthorizationList>(xml);

Note that the root XML element will also need to match that type name also.

<AuthorizationList>
<authorizations>
  <id>111</id>
  <name>Name 1</name>
  <Lists>
    <List>
      <id>1</id>
      <id>2</id>
    </List>
  </Lists>
</authorizations>
<authorizations>
  <id>222</id>
  <name>Name 2</name>
  <List />
</authorizations>
<authorizations>
  <id>333</id>
  <name>Name 3</name>
  <List />
</authorizations>
</AuthorizationList>
blins
  • 2,515
  • 21
  • 32
  • Is giving me the same error, and dont understand why to wrap with root element if its not being used in the code. – RSmart Aug 05 '16 at 16:57
  • I was just showing one approach that makes it clear that you don't need to define your `AuthorizationList` type purely to satisfy the serializer. The `ArrayOf...` root element is the default convention that the `XmlSerializer` will expect where `...` is the name of the generic type parameter. Again, this is assuming you would want to simplify and just leverage `List` instead of having to define `AuthorizationList` just to satisfy the root element requirement. I will edit and add an alternative approach that keeps your `AuthorizationList` since maybe you need that? – blins Aug 05 '16 at 17:40
  • See my edit which shows an alternative that keeps your `AuthorizationList` type and makes it the root in the xml. – blins Aug 05 '16 at 17:54