C# XML 反序列化 return 列表类型没有元素

C# XML deserialization return no element for list type

指的是 我之前问过关于 XML 反序列化的问题。

XML 对象:

[XmlRoot(ElementName = "root")]
public class RootMIR
{
    [XmlArray(ElementName = "MIRs")]
    public List<MIR> MIRs { get; set; }
}



[XmlRoot(ElementName = "MIR")]
public class MIR
{
    [XmlElement(ElementName = "issue_data")]
    public IssueData IssueData { get; set; }

    [XmlElement(ElementName = "reply_data")]
    public ReplyData ReplyData { get; set; }

    [XmlElement(ElementName = "receive_data")]
    public ReceiveData ReceiveData { get; set; }

    /*[XmlElement(ElementName = "items")]
    public Items Items { get; set; }*/

    [XmlArray(ElementName = "items")]
    public List<Item> Items { get; set; }

    [XmlElement(ElementName = "submission_data")]
    public SubmissionData SubmissionData { get; set; }

    [XmlIgnore]
    public int ID { get; set; }
    [XmlAttribute(AttributeName = "id")]
    public string ID_text
    {
        get { return ID.ToString(); }
        set { ID = Convert.ToInt32(value); }
    }


    [XmlAttribute(AttributeName = "number")]
    public string _numberText;
    [XmlIgnore]
    public int? Number
    {
        get { return _numberText == "" ? (int?)null : Convert.ToInt32(_numberText); }
        set { _numberText = value == null ? "" : value.ToString(); }
    }
    /*[XmlIgnore]
    public int? Number
    {
        get { return Number_text == "" ? (int?)null : Convert.ToInt32(Number_text); }
        set { Number_text = value.ToString(); }
    }
    [XmlAttribute(AttributeName = "number")]
    public string Number_text { get; set; }*/


    [XmlIgnore]
    public int? Revision
    {
        get { return Revision_text == "" ? (int?)null : Convert.ToInt32(Revision_text); }
        set { Revision_text = value == null ? "" : value.ToString(); }
    }
    [XmlAttribute(AttributeName = "revision")]
    public string Revision_text { get; set; }

}



[XmlRoot(ElementName = "issue_data")]
public class IssueData
{
    [XmlIgnore]
    public DateTime? IssueDate { get; set; }
    [XmlElement(ElementName = "issue_date")]
    public string IssueDateText
    {
        get { return (IssueDate.HasValue ? IssueDate.ToString() : null); }
        set { IssueDate = Convert.ToDateTime(value); }
    }


    [XmlElement(ElementName = "from")]
    public string From { get; set; }


    [XmlElement(ElementName = "to")]
    public string To { get; set; }


    [XmlElement(ElementName = "author")]
    public string Author { get; set; }


    [XmlElement(ElementName = "attn")]
    public string Attn { get; set; }


    [XmlElement(ElementName = "field")]
    public string Field { get; set; }


    [XmlElement(ElementName = "material_group")]
    public string MaterialGroup { get; set; }


    [XmlElement(ElementName = "related_sub")]
    public string RelatedSub { get; set; }
}



[XmlRoot(ElementName = "reply_data")]
public class ReplyData
{
    [XmlElement(ElementName = "reply_date")]
    public string ReplyDate { get; set; }

    [XmlElement(ElementName = "action_code")]
    public string ActionCode { get; set; }

    [XmlElement(ElementName = "reply_from")]
    public string ReplyFrom { get; set; }
}



[XmlRoot(ElementName = "receive_data")]
public class ReceiveData
{
    [XmlElement(ElementName = "receive_date")]
    public string ReceiveDate { get; set; }

    [XmlElement(ElementName = "receive_by")]
    public string ReceiveBy { get; set; }
}



[XmlRoot(ElementName = "item")]
public class Item
{
    [XmlElement(ElementName = "serial")]
    public string Serial { get; set; }

    [XmlElement(ElementName = "boq_code")]
    public string BoqCode { get; set; }

    [XmlElement(ElementName = "item_details")]
    public string ItemDetails { get; set; }

    [XmlElement(ElementName = "model")]
    public string Model { get; set; }

    [XmlElement(ElementName = "manufacturer")]
    public string Manufacturer { get; set; }

    [XmlElement(ElementName = "size")]
    public string Size { get; set; }

    [XmlElement(ElementName = "uom")]
    public string UoM { get; set; }

    [XmlElement(ElementName = "qty")]
    public string Quantity { get; set; }

    [XmlElement(ElementName = "approval")]
    public string Approval { get; set; }

    [XmlElement(ElementName = "approved_qty")]
    public string ApprovedQuantity { get; set; }

    [XmlElement(ElementName = "is_lumbsum")]
    public string IsLumbsum { get; set; }
}



[XmlRoot(ElementName = "submission_data")]
public class SubmissionData
{
    //[XmlElement(ElementName = "submitted")]
    //public string Submitted { get; set; }

    [XmlElement(ElementName = "status")]
    public string Status { get; set; }
}

而对于序列化器对象,

代码:

public static void ReloadDocumentFromDisk()
{
    using (FileStream fileStream = new FileStream(BaseDir + FileName + Extension, FileMode.Open))
    {
        DocMIR = (RootMIR)serializer.Deserialize(fileStream);
    }
}

问题是我得到了 List<Item> 的空列表,但 List<MIR> 运行正常,我检查了我的代码很多次,但我没有发现它有什么问题我错过了什么。

这是我得到的我添加了一个断点来检查我的代码:

MIR 的数量是 10,因为我的 XML 文件中有 10 个元素,但每个 MIR 中的项目数量是 0

您需要使用 XmlArrayItem 属性来指示每个 "item" 的元素名称与 Item 的要反序列化的 class 名称不同.

[XmlArray(ElementName = "items")]
[XmlArrayItem(ElementName = "item")]
public List<Item> Items { get; set; }

如果您的 Item class 被称为 item,那么在没有 XmlArrayItem 的情况下也可以正常工作。这就是为什么仅使用 XmlArray 属性时 MIRMIRs 属性 的使用效果很好,因为内部元素的 class 名称完全匹配.

日期时间不能为空。所以你需要能够处理 datetime 为空的情况。所以我把它变成了一个新的 DateTime()。请参阅下面我用您的 xml

测试的代码

注意:在您之前的帖子中回答了您关于如何使用 Xml Linq 来使用匿名解析来解析 xml 的问题。

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            IFormatProvider provider = CultureInfo.InvariantCulture;
            var results = doc.Descendants("MIR").Select(mir => new
            {
                Number = (string)mir.Attribute("number"),
                Revision = (string)mir.Attribute("revision"),
                From = (string)mir.Element("issue_data").Element("from"),
                Material = (string)mir.Element("issue_data").Element("material_group"),
                Field = (string)mir.Element("issue_data").Element("field"),
                Submittal = (string)mir.Element("issue_data").Element("related_sub"),
                To = (string)mir.Element("issue_data").Element("to"),
                Atten = (string)mir.Element("issue_data").Element("attn"),
                IssueDate =   DateTime.ParseExact((string)mir.Descendants("issue_date").FirstOrDefault(), "dd-M-yyyy",provider),
                ReplyDate = (string)mir.Descendants("receive_date").FirstOrDefault() == string.Empty ? new DateTime() : DateTime.ParseExact((string)mir.Descendants("receive_date").FirstOrDefault(), "dd-M-yyyy", provider),
                ActionCode = (string)mir.Element("reply_data").Element("action_code"),
                Author = (string)mir.Element("issue_data").Element("author"),
                IsSubmitted = (string)mir.Element("submission_data").Element("submitted"),
                Status = (string)mir.Element("submission_data").Element("status")
            }).First();
        }
    }
}