[英]XML Serializes Properly but Cannot Deserialize Array Objects
我有一個需要序列化XML的項目。 Java庫和C#.NET 4.0庫均以我的XSD為目標。 我的C#庫似乎在反序列化特定XML時遇到問題。
這是有問題的XML。
<FbiXml>
<Ticket>
<UserID>1</UserID>
<Key>qqym2OmtNjiUOBDbfr2tXg==</Key>
</Ticket>
<FbiMsgsRs statusCode="1000">
<SaveSORs statusCode="1000">
<SalesOrder>
<ID>517</ID>
<Note/>
<TotalPrice>0.07</TotalPrice>
<TotalTax>0</TotalTax>
<ItemTotal>0</ItemTotal>
<Salesman/>
<Number>629</Number>
<Status>20</Status>
<Carrier>Delivery</Carrier>
<FirstShipDate>2013-12-20T08:43:46</FirstShipDate>
<CreatedDate>2013-12-20T08:43:46</CreatedDate>
<IssuedDate>2013-12-20T08:43:46</IssuedDate>
<TaxRateName>None</TaxRateName>
<ShippingTerms>Prepaid & Billed</ShippingTerms>
<PaymentTerms>COD</PaymentTerms>
<CustomerContact/>
<CustomerName>Stackoverflow</CustomerName>
<CustomerID>19</CustomerID>
<FOB>Origin</FOB>
<QuickBooksClassName>None</QuickBooksClassName>
<LocationGroup>Main</LocationGroup>
<PoNum/>
<PriceIsHomeCurrency>true</PriceIsHomeCurrency>
<BillTo/>
<Ship/>
<Cost>0</Cost>
<Items>
<SalesOrderItem>
<ID>3725</ID>
<ProductNumber/>
<SOID>-1</SOID>
<Description>Adjustment Amount</Description>
<Taxable>false</Taxable>
<Quantity>1</Quantity>
<ProductPrice>0.07</ProductPrice>
<TotalPrice>0.07</TotalPrice>
<UOMCode>ea</UOMCode>
<ItemType>11</ItemType>
<Status>-1</Status>
<Note/>
<QuickBooksClassName/>
<NewItemFlag>true</NewItemFlag>
<LineNumber>1</LineNumber>
<AdjustmentAmount>0</AdjustmentAmount>
<AdjustPercentage>0</AdjustPercentage>
<QtyFulfilled>0</QtyFulfilled>
<QtyPicked>0</QtyPicked>
<TotalCost>0</TotalCost>
<TaxID>1</TaxID>
<TaxRate>0.1</TaxRate>
<TaxCode>None</TaxCode>
</SalesOrderItem>
</Items>
</SalesOrder>
</SaveSORs>
</FbiMsgsRs>
</FbiXml>
我正在用此代碼測試C#庫。
using FishbowlSDK;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace TestFishbowlLibrary
{
class Program
{
static void Main(string[] args)
{
testSODeserialize();
}
public static void testSODeserialize()
{
String XML = Resource1.SOXMLTEST001;
FbiXml fbixml = new FbiXml();
System.Xml.Serialization.XmlSerializer xml = new System.Xml.Serialization.XmlSerializer(fbixml.GetType());
xml.UnknownAttribute += new XmlAttributeEventHandler(Serializer_UnknownAttribute);
xml.UnknownElement += new XmlElementEventHandler(Serializer_UnknownElement);
String rs = XML;
rs = rs.Replace(@"<FbiXml>", @"<FbiXml xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""FishbowlSDK"">");
StringReader sr = new StringReader(rs);
XmlTextReader xtr = new XmlTextReader(sr);
FbiXml Response = (FbiXml)xml.Deserialize(xtr);
SaveSORsType loadsors = (SaveSORsType)Response.FbiMsgsRs.Items[0];
SalesOrder so = loadsors.SalesOrder;
if (so.Items.Count == 0)
{
throw new Exception("This XML has Sales Order Items, but it deserialized none!");
}
}
private static void Serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
{
Console.WriteLine("Unknown Attribute");
Console.WriteLine("\t" + e.Attr.Name + " " + e.Attr.InnerXml);
Console.WriteLine("\t LineNumber: " + e.LineNumber);
Console.WriteLine("\t LinePosition: " + e.LinePosition);
}
private static void Serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
Console.WriteLine("Unknown Element");
Console.WriteLine("\t" + e.Element.Name + " " + e.Element.InnerXml);
Console.WriteLine("\t LineNumber: " + e.LineNumber);
Console.WriteLine("\t LinePosition: " + e.LinePosition);
}
}
}
這是完整XSD的片段。 只是銷售訂單對象。
<xs:element name="SalesOrder">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:integer" minOccurs="0" />
<xs:element name="Note" type="xs:string" minOccurs="0" />
<xs:element name="TotalPrice" type="xs:string" minOccurs="0" />
<xs:element name="TotalTax" type="xs:string" minOccurs="0" />
<xs:element name="ItemTotal" type="xs:string" minOccurs="0" />
<xs:element name="Salesman" type="xs:string" minOccurs="0" />
<xs:element name="Number" type="xs:string" minOccurs="0" />
<xs:element name="Status" type="xs:integer" minOccurs="0" />
<xs:element name="Carrier" type="xs:string" minOccurs="0" />
<xs:element name="FirstShipDate" type="xs:dateTime" minOccurs="0" />
<xs:element name="CreatedDate" type="xs:dateTime" minOccurs="0" />
<xs:element name="IssuedDate" type="xs:dateTime" minOccurs="0" />
<xs:element name="TaxRateName" type="xs:string" minOccurs="0" />
<xs:element name="ShippingTerms" type="xs:string" minOccurs="0" />
<xs:element name="PaymentTerms" type="xs:string" minOccurs="0" />
<xs:element name="CustomerContact" type="xs:string" minOccurs="0" />
<xs:element name="CustomerName" type="xs:string" />
<xs:element name="CustomerID" type="xs:integer" />
<xs:element name="FOB" type="xs:string" minOccurs="0" />
<xs:element name="QuickBooksClassName" type="xs:string" minOccurs="0" />
<xs:element name="LocationGroup" type="xs:string" minOccurs="0" />
<xs:element name="PoNum" type="xs:string" minOccurs="0" />
<xs:element name="BillTo" type="tns:BillType" minOccurs="0" />
<xs:element name="Ship" type="tns:ShipType" minOccurs="0" />
<xs:element name="IssueFlag" type="xs:boolean" default="false" />
<xs:element name="VendorPO" type="xs:string" minOccurs="0" />
<xs:element name="CustomerPO" type="xs:string" minOccurs="0" />
<xs:element name="TotalIncludesTax" type="xs:boolean" minOccurs="0" />
<xs:element name="TypeID" type="xs:integer" minOccurs="0" />
<xs:element name="URL" type="xs:string" minOccurs="0" />
<xs:element name="Cost" type="xs:double" minOccurs="0" />
<xs:element name="DateLastModified" type="xs:dateTime" minOccurs="0" />
<xs:element name="SalesmanInitials" type="xs:string" minOccurs="1" />
<xs:element ref="tns:CustomFields" minOccurs="0" />
<xs:element ref="tns:Memos" minOccurs="0" />
<xs:element ref="tns:Items" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
這是C#庫中的目標代碼。 它是用xsd2code生成的。
[System.Xml.Serialization.XmlArrayAttribute(Order = 35)]
[System.Xml.Serialization.XmlArrayItemAttribute("SalesOrderItem", IsNullable = false)]
public List<SalesOrderItem> Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
這就是我的測試代碼輸出的內容。
Unknown Element
PriceIsHomeCurrency true
LineNumber: 25
LinePosition: 52
Unknown Element
BillTo
LineNumber: 26
LinePosition: 14
Unknown Element
Ship
LineNumber: 27
LinePosition: 12
Unknown Element
Cost 0
LineNumber: 28
LinePosition: 19
Unknown Element
Items
<SalesOrderItem xmlns="FishbowlSDK">
<ID>3725</ID>
<ProductNumber />
<SOID>-1</SOID>
<Description>Adjustment Amount</Description>
<Taxable>false</Taxable>
<Quantity>1</Quantity>
<ProductPrice>0.07</ProductPrice>
<TotalPrice>0.07</TotalPrice>
<UOMCode>ea</UOMCode>
<ItemType>11</ItemType>
<Status>-1</Status>
<Note />
<QuickBooksClassName />
<NewItemFlag>true</NewItemFlag>
<LineNumber>1</LineNumber>
<AdjustmentAmount>0</AdjustmentAmount>
<AdjustPercentage>0</AdjustPercentage>
<QtyFulfilled>0</QtyFulfilled>
<QtyPicked>0</QtyPicked>
<TotalCost>0</TotalCost>
<TaxID>1</TaxID>
<TaxRate>0.1</TaxRate>
<TaxCode>None</TaxCode>
</SalesOrderItem>
LineNumber: 55
LinePosition: 13
所以我的C#知道有一個已知元素。 但為什么? 因為我可以以編程方式生成銷售訂單對象,並且XML已正確序列化。
我發現了問題。 它是“ PriceIsHomeCurrency”的Unknown元素,因為該對象的順序現在不同於反序列化程序預期的順序,因此認為Items元素是未知的。 修復此未知元素可解決序列化問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.