Search code examples
c#xmllistserializationxmlserializer

C# XML deserialization return no element for list type


Referring to a question I asked earlier about XML deserialization.

XML Objects:

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

And as for the serializer object,

code:

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

Problem is that I am getting empty list for List<Item> but List<MIR> is functioning properly, I checked my code many times but I didn't find what's wrong with it what am I missing.

This is the what I get I added a breakpoint to check my code:

Watch Window

The count of MIRs is 10 as I have 10 elements in my XML file but the count of Items in each MIR is 0


Solution

  • You need to use the XmlArrayItem attribute to indicate that the element name of each "item" is different to the class name you want to deserialize to of Item.

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

    If your Item class were called item, this would work fine without the XmlArrayItem. That is why your usage of MIR works fine for the MIRs property when only using the XmlArray attribute, because the class name of the inner element matches exactly.