XmlSerializer非名称空间反序列化列表

问题描述:

试图反序列化List。 即时得到以下错误:XmlSerializer非名称空间反序列化列表

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

看到别的quesitons,如:{"<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或元素。但是当我反序列化时仍然会出现相同的错误。

反序列化代码示例:

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

这不是一个*有效的*(期望通过'XmlSerializer')xml。有效的从''开始。您可以尝试在调用'Deserialize()'之前添加此行。另一件事是丢失数组项的容器(用'XmlRootAttribute'表示),请参阅[本](http://*.com/q/126155/1997232)。 – Sinatr

+0

'XmlSerializer'可以处理缺少XML声明的XML。但是,XML必须有且仅有一个[根元素](https://en.wikipedia.org/wiki/Root_element)。这个XML有多个根元素,所以根本就不是XML。 – dbc

+0

要尝试添加根元素并让你知道。感谢您的快速响应 – RSmart

这一切前提是你必须在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> 
+0

给了我同样的错误,并不明白为什么要包装根元素,如果它没有在代码中使用。 – RSmart

+0

我只是展示了一种方法,它明确表示您不需要定义纯粹为了满足序列化程序的“AuthorizationList”类型。 'ArrayOf ...'根元素是'XmlSerializer'预期的默认约定,其中'...'是泛型类型参数的名称。同样,这是假设你想简化和利用'List '而不是必须定义'AuthorizationList'来满足根元素的要求。我会编辑并添加一个可以保留你的'AuthorizationList'的替代方法,因为也许你需要这样吗? – blins

+0

查看我的编辑,它显示了一个替代方案,它保持您的'AuthorizationList'类型并使其成为xml中的根。 – blins