【问题标题】:XmlSerializer Deserializing List Without namespace没有命名空间的 XmlSerializer 反序列化列表
【发布时间】:2016-08-05 14:55:31
【问题描述】:

试图反序列化列表。 我收到以下错误:

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

【问题讨论】:

  • 这不是一个有效的XmlSerializer 预期的)xml。有效的从&lt;?xml version="1.0"?&gt; 开始。您可以尝试在调用Deserialize() 之前添加此行。另一件事是缺少用于数组项的容器(由 XmlRootAttribute 表示),请参见例如this.
  • XmlSerializer 可以处理缺少 XML 声明的 XML。但是,XML 必须只有一个root element。这个 XML 有多个根元素,所以根本不是真正的 XML。
  • 将尝试添加根元素并通知您。感谢您的快速响应
  • 如果您的“XML”确实缺少单个根元素,请查看XML parser, multipule rootsC# XDocument Load with multiple rootsThere are multiple root elements load xml
  • 向 XML 添加根元素解决了该错误。但是现在反序列化返回0计数,还在验证中。

标签: c# xml serialization


【解决方案1】:

这一切的前提是假设您对 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&lt;T&gt; 与之前的解决方案一样。

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>

【讨论】:

  • 给了我同样的错误,并且不明白为什么在代码中没有使用根元素时要包装它。
  • 我只是展示了一种方法,它清楚地表明您不需要纯粹为了满足序列化程序而定义您的 AuthorizationList 类型。 ArrayOf... 根元素是XmlSerializer 所期望的默认约定,其中... 是泛型类型参数的名称。同样,这是假设您希望简化并仅利用 List&lt;T&gt; 而不必定义 AuthorizationList 以满足根元素要求。我将编辑并添加一种替代方法来保留您的AuthorizationList,因为也许您需要它?
  • 查看我的编辑,它显示了一个替代方案,它保留您的 AuthorizationList 类型并使其成为 xml 中的根。
猜你喜欢
  • 2015-06-30
  • 2021-11-03
  • 2011-12-09
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多