簡體   English   中英

XML正確序列化但無法反序列化數組對象

[英]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 &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已正確序列化。

我發現了問題。 它是“ PriceIsHomeCurrency”的Unknown元素,因為該對象的順序現在不同於反序列化程序預期的順序,因此認為Items元素是未知的。 修復此未知元素可解決序列化問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM