【问题标题】:Can't deserialize xml properly无法正确反序列化 xml
【发布时间】:2018-06-12 10:34:18
【问题描述】:

我有以下字符串要反序列化:

<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>

你注意到它有两个名为“服务”的标签,它们有不同的内容

这是我一直在使用的课程

[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; }
}

我尝试将服务标签作为数组处理,但它无法正常工作。我能够从最后一个标签中获取值,但不能从第一个标签中获取值。这两个标签都是必需的,所以我想知道是否有办法从两个标签中获取值?

【问题讨论】:

    标签: c# xml xml-deserialization


    【解决方案1】:

    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属性的字段。

    【讨论】:

      【解决方案2】:

      你不能有两个不同的元素同名。它不知道哪个标签属于哪里,您必须将名称更改为“MyServiceName”或类似的名称。

      【讨论】:

        【解决方案3】:

        如下更改你的类:

        [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; }
        }
        

        请选择适合您的名称,而不是 ServiceComplexServiceSimple

        订阅XmlSerializerUnknownElement 活动:

        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 手动填充类的属性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-16
          • 1970-01-01
          相关资源
          最近更新 更多