XmlSerializer反序列化列表没有命名空间

时间:2016-08-05 14:55:32

标签: c# xml serialization

尝试反序列化List。 我得到以下错误:

  

System.InvalidOperationException:XML文档中存在错误   (1,2)。 ---> System.InvalidOperationException:不是预期的。

看到其他问题,例如:{"<user xmlns=''> was not expected.} Deserializing Twitter XML,但这也无法解决我的问题。

这是一个Xml示例

<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>

该类创建如下:

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

尝试将列表更改为XmlArray,XmlArrayItem或Element。但是在反序列化时仍然会出现相同的错误。

反序列化代码示例:

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

1 个答案:

答案 0 :(得分:0)

这一切都是基于这样的假设,即您对xml的控制很少,并且没有太多改变的奢侈。正如其他人所指出的那样,它并没有很好地形成。这是一种使序列化工作的方法,只需对XML和类型进行最少的更改。首先删除AuthorizationList类型,并为您的授权类型分配XmlType属性(此步骤只是简单地复制名称以匹配您的xml如何)。

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

public class List { ... }

将xml包装在以下根元素中......

<ArrayOfAuthorizations>
...
</ArrayOfAuthorizations>

xml现在代表一个“授权”列表,所以反序列化就是这个......

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

另一种解决方案......

Authorizations成员更改为Authorization[]类型(数组类型而非单数)并拥有XmlElement属性(不是XmlArray)。将XmlType属性应用于Authorization(与上述解决方案一样,这是为了匹配xml,因为它具有每个数组元素的复数名称)。

[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; }
}

然后您反序列化AuthorizationList类型的实例,而不是前一个解决方案List<T>

AuthorizationList l = FromXml<AuthorizationList>(xml);

请注意,根XML元素也需要匹配该类型名称。

<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>