Десериализация XML во вложенный массив объектов - PullRequest
0 голосов
/ 30 ноября 2018

Я получаю 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;
    }
}

1 Ответ

0 голосов
/ 30 ноября 2018

В вашей модели данных есть две проблемы:

  1. В SavingType массив Savings должен быть помечен [XmlArray("Savings")], чтобы указать, чтоколлекция сериализуется с внешним контейнерным элементом <Savings> и внутренними элементами <Saving>:

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

    Вы первоначально пометили массив таким образом, затем закомментировали его и заменили на [XmlArray(ElementName = "Savings")], который указывает, что коллекция должна быть сериализована без внешнего элемента - который не отражает фактический XML.

  2. Исправив # 1, вы столкнетесь со второй проблемой,а именно, что значение 10,000.00 для <dailyBalance>10,000.00</dailyBalance> не может быть проанализировано как десятичное из-за присутствия запятой, и поэтому при десериализации возникает исключение.

    Чтобы решить эту проблему, выпотребуется изменить 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;
}

Образец скрипки здесь .

Кроме того, такие проблемы часто легко диагностировать путем создания экземпляра вашей модели в памяти, а затем сериализации в XML.Когда вы сравниваете сгенерированный XML с XML, который вы хотите десериализовать, любые различия в структуре будут указывать на ошибки в коде десериализации.

...