Не могу десериализовать XML должным образом - PullRequest
0 голосов
/ 12 июня 2018

У меня есть следующая строка для десериализации:

<result>
<error>
    <errorcode>0</errorcode>
    <errorge>წარმატებით</errorge>
    <errorru>Удачно</errorru>
    <erroren>successfully</erroren>
    <line>89</line>
</error>
<amount>
    <gel>1</gel>
</amount>
<user>01001</user>
<service>MyService</service> // here
<data>
    <nickname>popcorn2</nickname>
    <identification_name>identified</identification_name>
    <wallet_code>5554654</wallet_code>
    <NationalRate>1</NationalRate>
    <RATE>1</RATE>
    <GENERATED_AMOUNT>1</GENERATED_AMOUNT>
    <CURRENCY>GEL</CURRENCY>
</data>
<accoutant>
    <agentBenefit>0</agentBenefit>
    <agentCommission>0.44</agentCommission>
    <clientCommission>0</clientCommission>
</accoutant>
<service>
    <min_amount>0.49</min_amount>
    <max_amount>1500.00</max_amount>
    <currency>GEL</currency>
</service>
<avance>-134206.1500</avance>
<operation_status>0</operation_status>
</result>

, как вы заметили, у нее есть два тега с именем "service", и они имеют разное содержимое

вот класс, который я имеюЯ использовал

[XmlRoot(ElementName = "error")]
public class ErrorInfo
{
    [XmlElement(ElementName = "errorcode")]
    public string Errorcode { get; set; }
    [XmlElement(ElementName = "errorge")]
    public string Errorge { get; set; }
    [XmlElement(ElementName = "errorru")]
    public string Errorru { get; set; }
    [XmlElement(ElementName = "erroren")]
    public string Erroren { get; set; }
    [XmlElement(ElementName = "line")]
    public string Line { get; set; }
}

[XmlRoot(ElementName = "amount")]
public class Amount
{
    [XmlElement(ElementName = "gel")]
    public string Gel { get; set; }
}

[XmlRoot(ElementName = "data")]
public class Data
{
    [XmlElement(ElementName = "nickname")]
    public string Nickname { get; set; }
    [XmlElement(ElementName = "identification_name")]
    public string Identification_name { get; set; }
    [XmlElement(ElementName = "wallet_code")]
    public string Wallet_code { get; set; }
    [XmlElement(ElementName = "NationalRate")]
    public string NationalRate { get; set; }
    [XmlElement(ElementName = "RATE")]
    public string RATE { get; set; }
    [XmlElement(ElementName = "GENERATED_AMOUNT")]
    public string GENERATED_AMOUNT { get; set; }
    [XmlElement(ElementName = "CURRENCY")]
    public string CURRENCY { get; set; }
}

[XmlRoot(ElementName = "accoutant")]
public class Accoutant
{
    [XmlElement(ElementName = "agentBenefit")]
    public string AgentBenefit { get; set; }
    [XmlElement(ElementName = "agentCommission")]
    public string AgentCommission { get; set; }
    [XmlElement(ElementName = "clientCommission")]
    public string ClientCommission { get; set; }
}

[XmlRoot(ElementName = "service")]
public class Service
{
    [XmlElement(ElementName = "min_amount")]
    public string Min_amount { get; set; }
    [XmlElement(ElementName = "max_amount")]
    public string Max_amount { get; set; }
    [XmlElement(ElementName = "currency")]
    public string Currency { get; set; }
}

[XmlRoot(ElementName = "result")]
public class Result
{
    [XmlElement(ElementName = "error")]
    public ErrorInfo Error { get; set; }
    [XmlElement(ElementName = "amount")]
    public Amount Amount { get; set; }
    [XmlElement(ElementName = "user")]
    public string User { get; set; }
    [XmlElement(ElementName = "data")]
    public Data Data { get; set; }
    [XmlElement(ElementName = "accoutant")]
    public Accoutant Accoutant { get; set; }
    [XmlElement(ElementName = "service")]
    public Service[] Service { get; set; }
    [XmlElement(ElementName = "avance")]
    public string Avance { get; set; }
    [XmlElement(ElementName = "operation_status")]
    public string Operation_status { get; set; }
}

Я пытался обрабатывать служебные теги как массив, но он не мог работать.Я смог получить значения из последнего тега, но не из первого.оба тега необходимы, поэтому мне интересно, есть ли способ получить значения из обоих тегов?

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

Visual Studio имеет эту действительно замечательную функцию, где вы можете поместить свой XML в буфер обмена, а затем выполнить Правка -> Специальная вставка -> Вставить XML как классы.

Если вы сделаете это с вашим XML, он генерируетследующий класс для служебного тега:

/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class resultService
{

     private decimal min_amountField;

     private decimal max_amountField;

     private string currencyField;

     private string[] textField;

     /// <remarks/>
     public decimal min_amount
     {
          get
          {
                return this.min_amountField;
          }
          set
          {
                this.min_amountField = value;
          }
     }

     /// <remarks/>
     public decimal max_amount
     {
          get
          {
                return this.max_amountField;
          }
          set
          {
                this.max_amountField = value;
          }
     }

     /// <remarks/>
     public string currency
     {
          get
          {
                return this.currencyField;
          }
          set
          {
                this.currencyField = value;
          }
     }

     /// <remarks/>
     [System.Xml.Serialization.XmlTextAttribute()]
     public string[] Text
     {
          get
          {
                return this.textField;
          }
          set
          {
                this.textField = value;
          }
     }
}

Если вы хотите сделать это вручную, секрет заключается в том, чтобы добавить поле с атрибутом XmlTextAttribute.

0 голосов
/ 12 июня 2018

Измените ваши классы следующим образом:

[XmlRoot(ElementName = "result")]
public class Result
{
    // no need XmlElement attribute
    public ServiceComplex ServiceComplex { get; set; }

    // no need XmlElement attribute
    public string ServiceSimple { get; set; }

    // other properties
}

// no need XmlRoot attribute
public class ServiceComplex
{
    [XmlElement(ElementName = "min_amount")]
    public string Min_amount { get; set; }
    [XmlElement(ElementName = "max_amount")]
    public string Max_amount { get; set; }
    [XmlElement(ElementName = "currency")]
    public string Currency { get; set; }
}

Вместо ServiceComplex и ServiceSimple выберите подходящие вам имена.

Подписаться XmlSerializer на UnknownElement событие:

var xs = new XmlSerializer(typeof(Result));
xs.UnknownElement += Xs_UnknownElement;


private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
    if (e.Element.Name == "service")
    {
        var result = (Result)e.ObjectBeingDeserialized;
        if (e.Element.ChildNodes.Count == 1)
        {
            result.ServiceSimple = e.Element.InnerText;
        }
        else
        {
            result.ServiceComplex = new ServiceComplex
            {
                Min_amount = e.Element.SelectSingleNode("min_amount").InnerText,
                Max_amount = e.Element.SelectSingleNode("max_amount").InnerText,
                Currency = e.Element.SelectSingleNode("currency").InnerText
            };
        }
    }
}

В обработчике событий мы вручную заполняем свойства нашего класса из xml.

0 голосов
/ 12 июня 2018

Вы не можете иметь два разных элемента с одинаковым именем.Он не будет знать, к какому тегу относится, вы должны изменить имя на «MyServiceName» или что-то подобное.

...