XmlSerializer在Root上反序列化多个对象的数组/列表

时间:2009-12-22 11:43:03

标签: c# serialization xml-serialization xmlroot

我正在尝试反序列化以下XML输出:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Foo>
   <Val>Data1</Val>
</Foo>
<Foo>
   <Val>Data2</Val>
</Foo>

(这是从硬件设备输出,不能更改)

我有一个XML类型定义为:

    [XmlType(AnonymousType=true, Namespace="")]
    public class Foo
    {
        public string Val { get; set; }
    }

我尝试通过创建如下序列化程序来反序列化此数组:

  var s = new XmlSerializer(typeof(Foo[]));
  //or
  var s = new XmlSerializer(typeof(List<Foo>);

但是每次调用s.Deserialize()都会导致InvalidOperaitonException:

 System.InvalidOperationException: <Foo xmlns=''> was not expected.

注意

 var s = new XmlSerializer(typeof(Foo));
 // Only deseralizes the first Foo (Data1).

感谢您的帮助。

6 个答案:

答案 0 :(得分:8)

我认为问题出在你提供的xml上。

测试应用说

List<Foo> list = new List<Foo> {new Foo {Val = "Data1"}, new Foo {Val = "Data2"}};
var s = new XmlSerializer(typeof(List<Foo>));
StringBuilder sb = new StringBuilder();
XmlWriter wr = XmlWriter.Create(sb);
s.Serialize(wr, list);

string ss = sb.ToString();

var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr);

XML应该是

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfFoo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Foo>
        <Val>Data1</Val>
    </Foo>
    <Foo>
        <Val>Data2</Val>
    </Foo>
</ArrayOfFoo>

如果你可以删除初始线

<?xml version="1.0" encoding="ISO-8859-1"?>

将字符串缩减为

string s = "<ArrayOfFoo><Foo>   <Val>Data1</Val></Foo><Foo>   <Val>Data2</Val></Foo></ArrayOfFoo>";
var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(s);
List<Foo> list = (List<Foo>)s2.Deserialize(sr);

这可行。

答案 1 :(得分:7)

这不是有效的Xml。需要有一个核心根元素才能正常工作。

答案 2 :(得分:3)

这不是一个有效的xml,所以你不能像有效的xml那样反序列化它。你需要某种黑客来完成这项工作。我建议在xml的开头插入并插入xml的末尾。然后你可以反序列化它,因为你不能在xml那边做这个改变,在你的代码中做。

String ss; 
// lets assume this holds your xml data in string.
ss.append("</ArrayOfFoo>");
ss.replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "<?xml version=\"1.0\" encoding=\"utf-16\"?> <ArrayOfFoo>")

var s2 = new XmlSerializer(typeof(List<Foo>));
StringReader sr = new StringReader(ss);
List<Foo> returnList = (List<Foo>)s2.Deserialize(sr); 

现在这将返回正确的清单。

答案 3 :(得分:1)

正如其他海报所说,硬件设备生成的这种XML与.NET序列化/反序列化对象的方式不兼容。有效的XML和.NET需要有效的XML,并且有一个根元素。

我建议:

  • 要么修改获得的XML以匹配astander在其xml代码段中的显示方式。
  • 或者为您的文件编写一个简单的xml解析器,以便按需要反序列化文件

br,马塞尔

答案 4 :(得分:1)

从技术上讲,你所拥有的是而不是一个well-formed XML document(只有一个根元素),而是一个well-formed external parsed entity(可以有任意数量的元素)包含在其他元素中,以及未包含在任何元素中的文本)。因此,如果您的XML解析器具有解析EPE而不是文档的入口点,则应解析它。您还可以创建一个存根文档,该文档包含引用您的EPE并解析该文档。

答案 5 :(得分:0)

Xstream for .Net可能是一个有用的API