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

本文关键字:命名空间 列表 反序列化 XmlSerializer | 更新日期: 2023-09-27 18:01:05

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

System.InvalidOperationException:XML文档中存在错误(1,2(.-->不应为System.InvalidOperationException。

看到其他问题,如:{<userxmlns=';';>不是预期的。}反序列化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;
    }

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

这一切都是基于这样一个假设,即您对xml的控制最小,并且不需要对其进行太多更改。正如其他人所指出的,它的形式并不完善。这里有一种方法可以使序列化在对XML和类型进行最小更改的情况下工作。首先,去掉AuthorizationList类型,并为Authorization类型分配一个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"根元素包装XML:

<AuthorizationList>
...
</AuthorizationList>

然后反序列化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>