C# 如何将XML反序列化为对象?

C# 如何将XML反序列化为对象?,c#,.net,vb.net,C#,.net,Vb.net,我正在尝试将XML文档(invoiceList)转换为对象。理想情况下,我希望将其转换为对象集合(“发票”) 下面是XML的一个片段。我还包括了发票对象的一个片段。最后是我的反序列化尝试。我得到的错误信息是如此无用,以至于我不知道从哪里开始 <?xml version="1.0" encoding="utf-8"?> <invoiceListResponse> <invoiceList> <invoiceListI

我正在尝试将XML文档(invoiceList)转换为对象。理想情况下,我希望将其转换为对象集合(“发票”)

下面是XML的一个片段。我还包括了发票对象的一个片段。最后是我的反序列化尝试。我得到的错误信息是如此无用,以至于我不知道从哪里开始

<?xml version="1.0" encoding="utf-8"?>
    <invoiceListResponse>
       <invoiceList>
         <invoiceListItem>
            <invoiceUid>39165890</invoiceUid>
            <lastUpdatedUid>AAAAADrKwis=</lastUpdatedUid>
            <ccy>JPY</ccy>
            <autoPopulateFXRate>false</autoPopulateFXRate>
            <fcToBcFxRate>1.0000000000</fcToBcFxRate>
            <transactionType>S</transactionType>
            <invoiceDate>2013-12-26</invoiceDate>
            <utcFirstCreated>2013-12-26T08:12:22</utcFirstCreated>
            <utcLastModified>2013-12-26T08:12:22</utcLastModified>
            <summary />
            <invoiceNumber>W101010101</invoiceNumber>
我的代码:

Dim list As XmlDocument = proxy.Find(queries)
'Deserialize text file to a new object. 
    Using reader As XmlReader = XmlReader.Create(New StringReader(list.InnerXml))
      reader.MoveToContent()
      reader.Read()
      reader.Read()
      theinv = DirectCast(New XmlSerializer(GetType(Dto.InvoiceDto)).Deserialize(reader), Dto.InvoiceDto)
      Debug.Write(theinv.InvoiceNumber)
错误是:

“System.InvalidOperationException”类型的未处理异常 发生在System.Xml.dll中

附加信息:XML文档中有一个错误(1,74)


最简单的方法是创建一个与整个XML文档从根级别到下匹配的类。它不需要包含每个节点的属性,但它至少需要包含路径中每个元素的属性,以便从根元素到您关心的元素。例如,以下类将用于加载示例中的文档:

[XmlRoot("invoiceListResponse")]
public class InvoiceListResponse
{

    [XmlArray("invoiceList")]
    [XmlArrayItem("invoiceListItem")]
    public InvoiceDto[] InvoiceList;
}
然后,您可以将其反序列化为如下所示:

XmlSerializer s = new XmlSerializer(typeof(InvoiceListResponse));
using (FileStream f = new FileStream("Test.xml", System.IO.FileMode.Open))
{
    InvoiceListResponse response = (InvoiceListResponse)s.Deserialize(f);
}
Dim invoices As New List(Of InvoiceDto)()
Dim serializer As New XmlSerializer(GetType(InvoiceDto))
For Each i As XmlNode In doc.SelectNodes("/invoiceListResponse/invoiceList/invoiceListItem")
    Using reader As New StringReader("<invoice>" & i.InnerXml & "</invoice>")
        invoices.Add(DirectCast(serializer.Deserialize(reader), InvoiceDto))
    End Using
Next
编辑

根据您在下面的评论,您需要做的似乎是反序列化到确切的DTO类中,而无需对其进行任何修改。如果是这种情况,并且您不想像我在第一个示例中演示的那样创建包装器类,那么您始终可以执行以下操作:

XmlSerializer s = new XmlSerializer(typeof(InvoiceListResponse));
using (FileStream f = new FileStream("Test.xml", System.IO.FileMode.Open))
{
    InvoiceListResponse response = (InvoiceListResponse)s.Deserialize(f);
}
Dim invoices As New List(Of InvoiceDto)()
Dim serializer As New XmlSerializer(GetType(InvoiceDto))
For Each i As XmlNode In doc.SelectNodes("/invoiceListResponse/invoiceList/invoiceListItem")
    Using reader As New StringReader("<invoice>" & i.InnerXml & "</invoice>")
        invoices.Add(DirectCast(serializer.Deserialize(reader), InvoiceDto))
    End Using
Next
Dim发票作为新列表(发票编号)()
Dim序列化程序作为新的XmlSerializer(GetType(InvoiceDto))
对于doc.SelectNodes(“/invoiceListResponse/invoiceList/invoiceListItem”)中的每个i作为XmlNode
将读取器用作新的StringReader(“&i.InnerXml&”)
invoices.Add(DirectCast(序列化程序.反序列化(读取器),InvoiceDto))
终端使用
下一个

我已经很久没有进行序列化了,但我认为可能是标记不匹配。您的类需要一个名为“invoice”的标记,而在XML中它表示为“”。你有没有试着让这两个相同?你在C#中的类和你在VB中的代码?是的,类是由供应商提供的。消费应用程序是一个VB应用程序。谢谢Steven。我看到提供的Invoice类用于返回单个Invoice对象的REST调用,但我希望使用它包含返回的InvoiceList中的发票。也许我只需要按照您的建议为此创建一个全新的类。但我担心我会被嵌入项ArrayList卡住。可惜的是,没有任何方式来联系这里的大多数人在堆栈上的合同工作!我想,与其创建一个匹配所有xml元素的类,还不如在开始反序列化之前通过xmlDocument删除不需要的元素,嗯?我添加了一个示例,说明如何执行类似的操作。