【问题标题】:XML Deserialization to nested array of objectsXML反序列化为嵌套的对象数组
【发布时间】:2023-04-05 21:06:01
【问题描述】:

我正在从 Web 服务获取一些 XML。我建立了一些类来反序列化它。它部分工作;我得到任何SavingType 对象的原始成员的预期值。

正如代码所示,我得到一个应该有多个的 Saving 对象,并且它的字段为空。我对Savings 成员有一些注释属性(也许我应该更改这些名称)。这些属性似乎应该比我在那里的未注释的XmlElement 更正确,但是当我使用它们时,反序列化对象的Savings 成员始终是一个空数组。我的错误在哪里?

<Product xmlns="http://schemas.datacontract.org/2004/07/mInitechService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    ...
    <AdvSaving>
        <SavingType>...</SavingType>
        <SavingType>...</SavingType>
        <SavingType>
            <Savings>
                <Saving>
                    <apy>0.06</apy>
                    <dailyBalance>0.01</dailyBalance>
                    <divRate>0.06</divRate>
                    <name>Ultimate Checking </name>
                </Saving>
                <Saving>
                    <apy>0.10</apy>
                    <dailyBalance>10,000.00</dailyBalance>
                    <divRate>0.10</divRate>
                    <name>Ultimate Checking</name>
                </Saving>
                <Saving>
                    <apy>0.06</apy>
                    <dailyBalance>0.01</dailyBalance>
                    <divRate>0.06</divRate>
                    <name>Business Rewards Checking</name>
                </Saving>
            </Savings>
            <savingNote>All rates are subject to change without prior notification.  The APY figure assumes the principal and earned dividends remain on deposit until maturity.  Fees may reduce earnings.&#xD;
 &#xD;
1 Must meet age requirements to participate.</savingNote>
            <savingsMinBal>Minimum to open is $0.00</savingsMinBal>
            <savingsTypeName>Checking</savingsTypeName>
        </SavingType>
    </AdvSaving>
    <effectiveDate>Rates effective from 11/01/2018 through 11/30/2018</effectiveDate>
</Product>

还有课程:

namespace InitechServiceEntities
{
    [XmlType(AnonymousType = true, Namespace = "http://schemas.datacontract.org/2004/07/mInitechService")]
    [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/mInitechService", IsNullable = false)]
    public class Product
    {
        //...
        [XmlArrayItem("SavingType", typeof(SavingType), IsNullable = false)]
        public SavingType[] AdvSaving;
        [XmlElement("effectiveDate")]
        public string effectiveDate;
    }

    [XmlType("SavingType")]
    public class SavingType
    {
        [XmlElement("savingsTypeName")]
        public string savingsTypeName;
        [XmlElement("savingsMinBal")]
        public string savingsMinBal;
        [XmlElement("savingNote")]
        public string savingNote;
        [XmlElement("Savings")]
        //[XmlArray(ElementName = "Savings")]
        //[XmlArrayItem(Type = typeof(Saving))]
        public Saving[] Savings;
    }

    [XmlType("Saving")]
    public class Saving
    {
        [XmlElement("name")]
        public string name;
        [XmlElement("dailyBalance")]
        public decimal dailyBalance;
        [XmlElement("divRate")]
        public decimal divRate;
        [XmlElement("apy")]
        public decimal apy;
    }
}

【问题讨论】:

    标签: c# xml deserialization


    【解决方案1】:

    您的数据模型有两个问题:

    1. SavingType 中,Savings 数组必须用[XmlArray("Savings")] 标记,以表明该集合使用外部容器元素&lt;Savings&gt; 和内部元素&lt;Saving&gt; 进行序列化:

      // FIXED
      [XmlArray("Savings")]
      public Saving[] Savings;
      

      您最初以这种方式标记了数组,然后将其注释掉并用[XmlArray(ElementName = "Savings")] 替换它,这表明该集合应该在没有外部元素的情况下进行序列化——这并不反映实际的 XML。

    2. 修复了#1,你会遇到第二个问题,即&lt;dailyBalance&gt;10,000.00&lt;/dailyBalance&gt;的值10,000.00由于逗号的存在不能被解析为decimal,所以在反序列化过程中会抛出异常.

      要解决此问题,您需要将 Saving.dailyBalance 更改为 string,或引入手动解析的代理属性:

      // FIXED
      [XmlElement("dailyBalance")]
      public string dailyBalance;
      

    因此修改后的固定类型如下所示:

    [XmlType(AnonymousType = true, Namespace = "http://schemas.datacontract.org/2004/07/mInitechService")]
    [XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/mInitechService", IsNullable = false)]
    public class Product
    {
        [XmlArrayItem("SavingType", typeof(SavingType), IsNullable = false)]
        public SavingType[] AdvSaving;
        [XmlElement("effectiveDate")]
        public string effectiveDate;
    }
    
    [XmlType("SavingType")]
    public class SavingType
    {
        [XmlElement("savingsTypeName")]
        public string savingsTypeName;
        [XmlElement("savingsMinBal")]
        public string savingsMinBal;
        [XmlElement("savingNote")]
        public string savingNote;
    
        // FIXED
        //[XmlElement("Savings")]
        [XmlArray(ElementName = "Savings")]
        public Saving[] Savings;
    }
    
    [XmlType("Saving")]
    public class Saving
    {
        [XmlElement("name")]
        public string name;
    
        // FIXED
        [XmlElement("dailyBalance")]
        public string dailyBalance;
    
        [XmlElement("divRate")]
        public decimal divRate;
        [XmlElement("apy")]
        public decimal apy;
    }
    

    小提琴样本here.

    顺便说一句,通过在内存中构造模型实例,然后序列化为 XML,通常很容易诊断此类问题。当您将生成的 XML 与要反序列化的 XML 进行比较时,任何结构上的差异都将表明您的反序列化代码存在错误。

    【讨论】:

    • 当我看到你的帖子时,我只是在看dailyBalance。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多