1

我正在尝试反序列化以下 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).

谢谢你的帮助。

4

6 回答 6

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

那可以工作。

于 2009-12-22T12:03:08.383 回答
7

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

于 2009-12-22T12:01:28.510 回答
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); 

现在这将为您返回正确的列表。

于 2009-12-22T12:50:13.593 回答
1

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

我建议:

  • 要么你修改你获得的 XML 以匹配 asstander 在他的 xml 代码片段中呈现的方式。
  • 或者你为你的文件编写一个简单的 xml 解析器,它可以像你需要的那样反序列化文件

兄弟,马塞尔

于 2009-12-22T12:18:53.130 回答
1

从技术上讲,您所拥有的不是一个格式良好的 XML 文档(它只有一个根元素),而是一个格式良好的外部解析实体(它可以包含其他元素中不包含的任意数量的元素,以及文本不包含在任何元素中)。因此,它应该解析您的 XML 解析器是否有一个用于解析 EPE 而不是文档的入口点。您还可以创建一个存根文档,其中包含通过引用您的 EPE 并解析该文档。

于 2009-12-22T12:52:55.867 回答
0

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

于 2009-12-22T11:56:22.890 回答