2013-12-20 86 views
0

我有一個需要序列化XML的項目。我的XSD是由Java庫和C#.NET 4.0庫定位的。我的C#庫似乎有問題反序列化特定的XML。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 &amp; 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已正確序列化。

回答

0

我發現了這個問題。它是「PriceIsHomeCurrency」的未知元素,因爲該對象的順序現在與解串器期望的順序不同,因此認爲Items元素是未知的。修復這個未知元素解決了序列化問題。