【问题标题】:How to deserialize an array containing a list?如何反序列化包含列表的数组?
【发布时间】:2019-03-25 15:45:04
【问题描述】:

我想反序列化一个包含一些东西和 3 个列表的数组。 该程序运行良好,除了列表。列表已创建,但它们不包含任何内容!

你能帮帮我吗?

这是 xml 文件的样子:

<blind>
  <folder>C:\Users\Michael\Desktop\BT 1 normal\Programme BT\</folder>
  <nombre_titres>25</nombre_titres>
  <numero></numero>
  <theme></theme>
  <heure_debut></heure_debut>
  <mdp>a</mdp>
  <lien></lien>
  <playlist>
    <extrait>
      <artiste>Abba</artiste>
      <titre>Take a chance on me</titre>
      <PointAT>1.25</PointAT>
      <PointA>0.5</PointA>
      <PointT>0.5</PointT>
      <JoueursAT>
        <joueurAT>Ahkayaqua</joueurAT>
        <joueurAT>Angelene</joueurAT>
      </JoueursAT>
      <JoueursA>
        <joueurA></joueurA>
      </JoueursA>
      <JoueursT>
        <joueurT></joueurT>
      </JoueursT>
    </extrait>
<extrait>
....
</extrait>
 </playlist>
</blind>

我要反序列化的代码:

XElement xmle;
xmle = XElement.Load(_folder + "Blind.xml");
textBox1.Text = xmle.Element("numero").Value;
textBox4.Text = xmle.Element("theme").Value;
textBox3.Text = xmle.Element("heure_debut").Value;
textBox5.Text = xmle.Element("lien").Value;
textBox2.Text = xmle.Element("mdp").Value;                    
extraits = (from ex in xmle.Element("playlist").Elements("extrait")
            select new Extrait
                (ex.Element("artiste").Value,
                 ex.Element("titre").Value,
                 0,
                 0,
                 0,
                 (from jat in ex.Element("JoueursAT").Elements("JoueurAT")
                  select jat.Element("JoueurAT").Value).ToList(),
                 (from ja in ex.Element("JoueursA").Elements("JoueurA")
                  select ja.Element("JoueurA").Value).ToList(),
                 (from jt in ex.Element("JoueursT").Elements("JoueurT")
                  select jt.Element("JoueurT").Value).ToList())).ToArray();

这是我的课:

public class Extrait
{
    private String _Artiste;
    private String _Titre;
    private double _PointA;
    private double _PointT;
    private double _PointAT;
    private List<String> _JoueurA;
    private List<String> _JoueurT;
    private List<String> _JoueurAT;

    public String Artiste
    {
        get { return _Artiste; }
        set { _Artiste = value; }
    }

    public String Titre
    {
        get { return _Titre; }
        set { _Titre = value; }
    }

    public Double PointA
    {
        get { return _PointA; }
        set { _PointA = value; }
    }

    public Double PointT
    {
        get { return _PointT; }
        set { _PointT = value; }
    }

    public Double PointAT
    {
        get { return _PointAT; }
        set { _PointAT = value; }
    }

    public List<String> JoueurA
    {
        get { return _JoueurA; }
        set { _JoueurA = value; }
    }

    public List<String> JoueurT
    {
        get { return _JoueurT; }
        set { _JoueurT = value; }
    }

    public List<String> JoueurAT
    {
        get { return _JoueurAT; }
        set { _JoueurAT = value; }
    }

    public Extrait(String Artiste, String Titre, Double PointA, Double PointT, Double PointAT, List<String> JoueurAT, List<String> JoueurA, List<String> JoueurT)
    {
        _Artiste = Artiste;
        _Titre = Titre;
        _PointA = PointA;
        _PointT = PointT;
        _PointAT = PointAT;
        _JoueurAT = JoueurAT;
        _JoueurA = JoueurA;
        _JoueurT = JoueurT;
    }
}

好吧,我尝试了很多可能性,但都没有成功!

【问题讨论】:

  • 您使用 xml 进行 linq 而不是反序列化。要将 xml 反序列化为对象,请使用 XmlSerializer 类。

标签: c# xml linq-to-xml


【解决方案1】:

如果这是您的实际 xml,请查看内部标签 - 它们以小写字母开头。当您选择名称为 .Elements("JoueurAT") 的元素时,您的 xml 有 &lt;joueurAT&gt; - 节点名称区分大小写。

您的代码应如下所示:

extraits = (from ex in xmle.Element("playlist").Elements("extrait")
        select new Extrait
            (ex.Element("artiste").Value,
             ex.Element("titre").Value,
             0,
             0,
             0,
             (from jat in ex.Element("JoueursAT").Elements("joueurAT")
              select jat.Value).ToList(),
             (from ja in ex.Element("JoueursA").Elements("joueurA")
              select ja.Value).ToList(),
             (from jt in ex.Element("JoueursT").Elements("joueurT")
              select jt.Value).ToList())).ToArray();

【讨论】:

    【解决方案2】:

    这应该可以解决它。基本上默认行为是对列表使用两级嵌套(意味着它默认为[XmlArray] 加上[XmlArrayItem];这里只有一层,所以你需要告诉它。

    [XmlElement]
    public List<String> JoueurA
    {
        get { return _JoueurA; }
        set { _JoueurA = value; }
    }
    [XmlElement]
    public List<String> JoueurT
    {
        get { return _JoueurT; }
        set { _JoueurT = value; }
    }
    [XmlElement]
    public List<String> JoueurAT
    {
        get { return _JoueurAT; }
        set { _JoueurAT = value; }
    }
    

    顺便说一句;您可能会发现在这里使用诸如自动属性之类的东西更方便;常规属性和列表的示例:

    public double PointAT {get;set;}
    [XmlElement]
    public List<string> JoueurA {get;} = new List<string>();
    

    这比自己弄乱所有字段要方便得多。

    你可能还想确保你有一个公共的无参数构造函数;坦率地说,我只是 remove 自定义构造函数(在这种情况下:免费包含公共无参数构造函数),但除此之外 - 我只是添加:

    public Extrait() {}
    

    【讨论】:

    • OP实际上并没有反序列化,所以属性在这种情况下不起作用。检查“反序列化”代码
    【解决方案3】:

    盲人班需要改变

       [XmlRoot("blind")]
        public class Blind
        {
            [XmlArray("playlist")]
            [XmlArrayItem("extrait")]
            public List<Extrait> extrait { get; set; }
        }
        public class Extrait
        {
        }
    

    【讨论】:

      【解决方案4】:
      (from jat in ex.Element("JoueursAT").Elements("JoueurAT")
       select jat.Element("JoueurAT").Value).ToList()
      

      应该变成

      (from jat in ex.Element("JoueursAT").Elements("joueurAT")
       select jat.Value).ToList()
      

      我不确定 C# 的 XML 库在涉及到标记名称时是否区分大小写,但如果有疑问,最好还是谨慎行事。 尽管实际上已经对它们进行了循环,但您在进行选择时还尝试访问元素“joueurAT”,因此您可以直接访问 Value 属性。

      您也可以尝试扩展方法,而不是像您那样使用 LINQ,这往往更具可读性:

      xmle.Element("playlist").Elements("extrait")
          .Select(ex => new Extrait
          {
              Artiste = ex.Element("artiste").Value,
              Titre = ex.Element("titre").Value,
              PointA = 0,
              PointT = 0,
              PointAT = 0,
              JoueurA = ex.Element("JoueursAT").Elements("joueurAT").Select(jat => jat.Value).ToList(),
              JoueurT = ex.Element("JoueursA").Elements("joueurA").Select(ja => ja.Value).ToList(),
              JoueurAT = ex.Element("JoueursT").Elements("joueurT").Select(jt => jt.Value).ToList()
          });
      

      【讨论】:

      • 感谢您的回复,但它给出了一条错误消息:“没有给出与所需形式参数'Artiste'相对应的参数......”
      • 我的错,我修改了 Extrait 类以使用自动属性,所以这可能是问题
      猜你喜欢
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多