简体   繁体   English

XmlSerializer根反序列化多个对象的数组/列表

[英]XmlSerializer Deserializing Array/List of Multiple Objects at Root

I'm trying to deserialize the following XML output: 我正在尝试反序列化以下XML输出:

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

(This is output from a hardware device, and cannot be changed) (这是从硬件设备输出的,不能更改)

I have an XML type defined as: 我有一个XML类型定义为:

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

I've tried to deserialize this array by creating a serializer like: 我试图通过创建一个序列化器来反序列化此数组:

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

But every call to s.Deserialize() causes an InvalidOperaitonException: 但是每次对s.Deserialize()的调用都会导致InvalidOperaitonException:

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

Note 注意

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

Thanks for your help. 谢谢你的帮助。

I think the issue is with your provided xml. 我认为问题在于您提供的xml。

Test app says 测试应用程式说

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

And the XML should be 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>

If you can remove the inital line 如果可以删除首行

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

And minipulate the string into 并将字符串最小化为

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

That could work. 那行得通。

That isn't valid Xml. 那不是有效的Xml。 There needs to be a core root element for it to work properly. 要使其正常工作,需要有一个核心根元素。

this is not a valid xml so you can not deserialize it like a valid xml. 这不是有效的xml,因此您不能像有效的xml一样反序列化它。 You need some kind of hack to make this work. 您需要某种技巧来使其正常工作。 i'd suggest to insert at beginning of the xml and inserting at the end of xml. 我建议在xml的开头插入,在xml的末尾插入。 then you can deserialize it, since you cant make this change at xml side, do it in your code. 那么您可以反序列化它,因为您无法在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); 

now this shall return you the correct list. 现在,这将为您返回正确的列表。

As the other posters say, this XML that the hardware device produces is not compatible to the way .NET serializes/deserializes object. 就像其他张贴者所说的那样,硬件设备生成的XML与.NET序列化/反序列化对象的方式不兼容。 Valid XML, and .NET requires valid XML, has a root element. 有效的XML和.NET要求有效的XML具有根元素。

I suggest: 我建议:

  • either you modify your obtained XML to match the way astander presents in his xml code snippet. 您可以修改获取的XML以使其与旁观者在其xml代码段中的呈现方式相匹配。
  • or you write a simple xml parser for your file that deserializes the file like you need 或者您为文件编写一个简单的xml解析器,以根据需要反序列化文件

br, Marcel br,马塞尔

Technically, what you have there is not a well-formed XML document (which has exactly one root element), but rather an well-formed external parsed entity (which can have any number of elements not contained in other elements, as well as text not contained in any elements). 从技术上讲,您所拥有的不是一个格式正确的XML文档 (它只具有一个根元素),而是一个格式正确的外部解析实体 (可以具有其他元素中不包含的任何数量的元素以及文本)不包含在任何元素中)。 Therefore, it should parse if your XML parser has an entry point for parsing EPEs rather than documents. 因此,它应该解析XML解析器是否具有用于解析EPE而不是文档的入口点。 You could also create a stub document which includes by reference your EPE and parse that document. 您还可以创建一个存根文档,其中包含通过引用您的EPE并解析该文档。

.Net的Xstream可能是有用的API

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM