反序列化XML元素

时间:2016-11-30 10:01:23

标签: c# xml deserialization xml-deserialization

我在将XML反序列化为类时遇到了一些问题。

这是XML:

<?xml version="1.0" encoding="utf-8" ?>
<InterestRates>

  <!--Type A -->
  <InterestRates_A>
    <InterestRate_A>
      <ValidFrom></ValidFrom>
      <ValidTo>2004-12-31</ValidTo>
      <Rate>0.00000</Rate>
    </InterestRate_A>
    <InterestRate_A>
      <ValidFrom>2005-01-01</ValidFrom>
      <ValidTo>2005-12-31</ValidTo>
      <Rate>0.04247</Rate>
    </InterestRate_A>
    <InterestRate_A>
      <ValidFrom>2005-01-01</ValidFrom>
      <ValidTo>2005-12-31</ValidTo>
      <Rate>0.04247</Rate>
    </InterestRate_A>
    <InterestRate_A>
      <ValidFrom>2006-01-01</ValidFrom>
      <ValidTo>2006-12-31</ValidTo>
      <Rate>0.02986</Rate>
    </InterestRate_A>
    <InterestRate_A>
      <ValidFrom>2007-01-01</ValidFrom>
      <ValidTo>2009-10-30</ValidTo>
      <Rate>0.02740</Rate>
    </InterestRate_A>
    <InterestRate_A>
      <ValidFrom>2009-10-31</ValidFrom>
      <ValidTo>2009-10-30</ValidTo>
      <Rate>0.02470</Rate>
    </InterestRate_A>
  </InterestRates_A>

  <!--Type B -->
  <InterestRates_B>
    <InterestRate_B>
      <ValidFrom>2016-05-01</ValidFrom>
      <ValidTo></ValidTo>
      <Rate>0.05</Rate>
      <Rate2>2.05</Rate2>
    </InterestRate_B>
  </InterestRates_B>

  <!--Type C -->
  <InterestRates_C>
    <InterestRate_C>
      <ValidFrom>2017-01-01</ValidFrom>
      <ValidTo></ValidTo>
      <Rate>2</Rate>
    </InterestRate_C>
  </InterestRates_C>

  <!--Type D -->
  <InterestRates_D>
    <InterestRate_D>
      <ValidFrom>2017-01-01</ValidFrom>
      <ValidTo></ValidTo>
      <Rate>3</Rate>
    </InterestRate_D>
  </InterestRates_D>

  <!--Type E -->
  <InterestRates_E>
    <InterestRate_E>
      <ValidFrom>2017-01-01</ValidFrom>
      <ValidTo></ValidTo>
      <Rate>5</Rate>
    </InterestRate_E>
  </InterestRates_E>

  <!--Type F -->
  <InterestRates_F>
    <InterestRate_F>
      <ValidFrom>2017-01-01</ValidFrom>
      <ValidTo></ValidTo>
      <Rate>7</Rate>
    </InterestRate_F>
  </InterestRates_F>

</InterestRates>

这是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace Interest
{
  // Root class
  [XmlRoot("InterestRates")]
  public class InterestRates
  {
      [XmlElement("InterestRates_A")]
      public InterestRates_A InterestRates_A { get; set; }

      [XmlElement("InterestRates_B")]
      public InterestRates_B InterestRates_B { get; set; }

      [XmlElement("InterestRates_C")]
      public InterestRates_C InterestRates_C { get; set; }

      [XmlElement("InterestRates_D")]
      public InterestRates_D InterestRates_D { get; set; }

      [XmlElement("InterestRates_E")]
      public InterestRates_E InterestRates_E { get; set; }

      [XmlElement("InterestRates_F")]
      public InterestRates_F InterestRates_F { get; set; }
  }


  [XmlType("InterestRates_A")]
  public class InterestRates_A
  {
    [XmlArrayItem("InterestRate_A", typeof(InterestRate_A))]
    public InterestRate_A[] InterestRate_A { get; set; }
  }

  [XmlType("InterestRates_B")]
  public class InterestRates_B
  {
    [XmlArray("InterestRate_B")]
    [XmlArrayItem("InterestRate_B", typeof(InterestRate_B))]
    public InterestRate_B[] InterestRate_B { get; set; }
  }

  [XmlType("InterestRates_C")]
  public class InterestRates_C
  {
    [XmlArray("InterestRate_C")]
    [XmlArrayItem("InterestRate_C", typeof(InterestRate_C))]
    public InterestRate_C[] InterestRate_C { get; set; }
  }

  [XmlType("InterestRates_D")]
  public class InterestRates_D
  {
    [XmlArray("InterestRate_D")]
    [XmlArrayItem("InterestRate_D", typeof(InterestRate_D))]
    public InterestRate_D[] InterestRate_D { get; set; }
  }

  [XmlType("InterestRates_E")]
  public class InterestRates_E
  {
    [XmlArray("InterestRate_E")]
    [XmlArrayItem("InterestRate_E", typeof(InterestRate_E))]
    public InterestRate_E[] InterestRate_E { get; set; }
  }

  [XmlType("InterestRates_F")]
  public class InterestRates_F
  {
    [XmlArray("InterestRate_F")]
    [XmlArrayItem("InterestRate_F", typeof(InterestRate_F))]
    public InterestRate_F[] InterestRate_F { get; set; }
  }


  [Serializable]
  public class InterestRate_A
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

   [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }
  }

  [Serializable]
  public class InterestRate_B
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }

    [XmlElement("Rate2")]
    public string Rate2 { get; set; }
  }

  [Serializable]
  public class InterestRate_C
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }
  }

  [Serializable]
  public class InterestRate_D
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }
  }

  [Serializable]
  public class InterestRate_E
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }
  }

  [Serializable]
  public class InterestRate_F
  {
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }
  }
}

当我将XML反序列化到我的根类InterestRates时,所有InterestRate_X个集合都是空的。如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

反序列化不起作用的原因是您已使用[XmlArray]InterestRates_X类型中标记了利率数组,例如:

  [XmlType("InterestRates_B")]
  public class InterestRates_B
  {
    [XmlArray("InterestRate_B")]
    [XmlArrayItem("InterestRate_B", typeof(InterestRate_B))]
    public InterestRate_B[] InterestRate_B { get; set; }
  }

这表明InterestRate_X集合将在容器元素中序列化,如下所示:

<InterestRates>
  <InterestRates_B>
    <InterestRate_B> <!--The extra [XmlArray] container element -->
      <InterestRate_B>
        <ValidFrom>2016-05-01</ValidFrom>
        <ValidTo></ValidTo>
        <Rate>0.05</Rate>
        <Rate2>2.05</Rate2>
      </InterestRate_B>
    </InterestRate_B>

由于您的实际XML没有这种额外的嵌套级别,因此反序列化失败。

解决方案是使用[XmlElement]

[XmlType("InterestRates_A")]
public class InterestRates_A
{
    [XmlElement("InterestRate_A")]
    public InterestRate_A[] InterestRate_A { get; set; }
}

[XmlType("InterestRates_B")]
public class InterestRates_B
{
    [XmlElement("InterestRate_B")]
    public InterestRate_B[] InterestRate_B { get; set; }
}

[XmlType("InterestRates_C")]
public class InterestRates_C
{
    [XmlElement("InterestRate_C")]
    public InterestRate_C[] InterestRate_C { get; set; }
}

[XmlType("InterestRates_D")]
public class InterestRates_D
{
    [XmlElement("InterestRate_D")]
    public InterestRate_D[] InterestRate_D { get; set; }
}

[XmlType("InterestRates_E")]
public class InterestRates_E
{
    [XmlElement("InterestRate_E")]
    public InterestRate_E[] InterestRate_E { get; set; }
}

[XmlType("InterestRates_F")]
public class InterestRates_F
{
    [XmlElement("InterestRate_F")]
    public InterestRate_F[] InterestRate_F { get; set; }
}

示例fiddle

或者,您可以完全删除中间InterestRates_X类型,并将所有InterestRate_X类型合并为一种类型,从而简化数据模型,如下所示:

[XmlRoot("InterestRates")]
public class InterestRates
{
    [XmlArray("InterestRates_A")]
    [XmlArrayItem("InterestRate_A")]
    public InterestRate [] InterestRates_A { get; set; }

    [XmlArray("InterestRates_B")]
    [XmlArrayItem("InterestRate_B")]
    public InterestRate [] InterestRates_B { get; set; }

    [XmlArray("InterestRates_C")]
    [XmlArrayItem("InterestRate_C")]
    public InterestRate [] InterestRates_C { get; set; }

    [XmlArray("InterestRates_D")]
    [XmlArrayItem("InterestRate_D")]
    public InterestRate [] InterestRates_D { get; set; }

    [XmlArray("InterestRates_E")]
    [XmlArrayItem("InterestRate_E")]
    public InterestRate [] InterestRates_E { get; set; }

    [XmlArray("InterestRates_F")]
    [XmlArrayItem("InterestRate_F")]
    public InterestRate [] InterestRates_F { get; set; }
}

public class InterestRate
{
    [XmlElement("ValidFrom")]
    public string ValidFrom { get; set; }

    [XmlElement("ValidTo")]
    public string ValidTo { get; set; }

    [XmlElement("Rate")]
    public string Rate { get; set; }

    [XmlElement("Rate2")]
    public string Rate2 { get; set; }
}

示例fiddle #2