我正在尝试将XML doc(invoiceList)转换为对象。理想情况下,我想将其转换为对象集合(“发票”)。
下面是XML的一个片段。我还在INVOICE对象中包含了一个片段。最后我尝试反序列化。我得到的错误消息是如此无用,以至于我不知道从哪里开始。
<?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>
发票对象代码的片段
[XmlRoot(ElementName = "invoice")]
public class InvoiceDto : TransactionDto
{
public InvoiceDto()
{
TradingTerms = new TradingTermsDto();
QuickPayment = new QuickPaymentDto();
}
public InvoiceDto(string transactionType, string layout)
{
Layout = layout;
TransactionType = transactionType;
TradingTerms = new TradingTermsDto();
QuickPayment = new QuickPaymentDto();
}
[XmlElement(ElementName = "transactionType")]
public string TransactionType;
[XmlElement(ElementName = "invoiceType")]
public string InvoiceType;
[XmlElement(ElementName = "contactUid")]
public int ContactUid;
[XmlElement(ElementName = "shipToContactUid")]
public int ShipToContactUid;
[XmlElement(ElementName = "externalNotes")]
public string ExternalNotes;
我的代码:
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)。
答案 0 :(得分:1)
最简单的方法是创建一个与其根级别的整个 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);
}
修改强>
根据您在下面的评论,您需要做的是反序列化到确切的DTO类,而不对其进行任何修改。如果是这种情况,并且你不想像我在第一个例子中演示的那样创建一个包装类,你总是可以这样做:
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