简体   繁体   中英

C# xml deserialization won't pick up child elements into list

I can't figure out why this doesn't work, I searched for answer and when I sum up everything this should work but somehow it doesn't. So I have a Bill class which has some properties that are deserialized fine, but I have property List articles which comes up empty.

past of Bill class

[Serializable()]
[XmlRoot("Bills")]
public class Bill
{
    private DateTime dateTimePrivate;
    
    **[XmlArray("Bill")]
    [XmlArrayItem("Article", typeof(Article))]
    public List<Article> articles { get; set; }**
    [XmlAttribute("User")]
    public string user { get; set; } //Username
    [XmlAttribute("Total")]
    public int totalPrice { get; set; }
    [XmlAttribute("ID")]
    public int id { get; set; }

Article class

[Serializable()]
[XmlRoot("Article")]
public class Article
{
    [XmlAttribute("ID")]
    public int ID { get; set; }
    [XmlAttribute("name")]
    public string name { get; set; }
    [XmlAttribute("buttonName")]
    public string buttonName { get; set; }
    [XmlAttribute("price")]
    public float price { get; set; }
    [XmlAttribute("quantity")]
    public float quantity { get; set; } //Namijenjeno samo za racune
    [XmlAttribute("totalPrice")]
    public float totalPrice { get { return price * quantity; } set { totalPrice = price * quantity; } }

AllBIlls.xml

<?xml version="1.0" encoding="utf-8"?>
<BillsCollection>
   <Bills>
      <Bill ID="0" Time="06-12-2020 13:28" User="TEST" SavedToDatabase="TEST" Total="24">
        <Article ID="0" name="CocaCola" quantity="1" price="12" totalPrice="12" />
        <Article ID="1" name="Sprite" quantity="1" price="12" totalPrice="12" />
    </Bill>
    <Bill ID="1" Time="06-12-2020 13:28" User="TEST" SavedToDatabase="TEST" Total="36">
        <Article ID="0" name="CocaCola" quantity="2" price="12" totalPrice="24" />
        <Article ID="1" name="Sprite" quantity="1" price="12" totalPrice="12" />
    </Bill>
 </Bills>
</BillsCollection>

Deserialization

public static BillList GetBills()
    {
        Console.WriteLine("reading bills");

        BillList allBills = null;

        //Adding root element for serialziation
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "BillsCollection";
        xRoot.IsNullable = true;

        XmlSerializer serializer = new XmlSerializer(typeof(BillList), xRoot);
        XmlReader reader = AllBillsXml.CreateReader();

        allBills = (BillList)serializer.Deserialize(reader);
        reader.Close();

        Console.WriteLine("reading succesful");

        return allBills;
    }

Did you tried using XmlTextReader instead of XmlReader? This might help you.

I used this site https://json2csharp.com/xml-to-csharp along with the xml you provided and i can deserialize the Articles collection just fine.

Here are the classes generated:

// using System.Xml.Serialization;
    // XmlSerializer serializer = new XmlSerializer(typeof(BillsCollection));
    // using (StringReader reader = new StringReader(xml))
    // {
    //    var test = (BillsCollection)serializer.Deserialize(reader);
    // }

    [XmlRoot(ElementName = "Article")]
    public class Article
    {

        [XmlAttribute(AttributeName = "ID")]
        public String ID { get; set; }

        [XmlAttribute(AttributeName = "name")]
        public String Name { get; set; }

        [XmlAttribute(AttributeName = "quantity")]
        public String Quantity { get; set; }

        [XmlAttribute(AttributeName = "price")]
        public String Price { get; set; }

        [XmlAttribute(AttributeName = "totalPrice")]
        public String TotalPrice { get; set; }
    }

    [XmlRoot(ElementName = "Bill")]
    public class Bill
    {

        [XmlElement(ElementName = "Article")]
        public List<Article> Article { get; set; }

        [XmlAttribute(AttributeName = "ID")]
        public String ID { get; set; }

        [XmlAttribute(AttributeName = "Time")]
        public String Time { get; set; }

        [XmlAttribute(AttributeName = "User")]
        public String User { get; set; }

        [XmlAttribute(AttributeName = "SavedToDatabase")]
        public String SavedToDatabase { get; set; }

        [XmlAttribute(AttributeName = "Total")]
        public String Total { get; set; }
    }

    [XmlRoot(ElementName = "Bills")]
    public class Bills
    {

        [XmlElement(ElementName = "Bill")]
        public List<Bill> Bill { get; set; }
    }

    [XmlRoot(ElementName = "BillsCollection")]
    public class BillsCollection
    {

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

And here is the Articles object filled: 在此处输入图像描述

And here's the deserialization code:

           XmlSerializer serializer = new XmlSerializer(typeof(BillsCollection));

            using (StreamReader reader = new StreamReader(@"Path to xml.xml"))
            {
                var test = (BillsCollection)serializer.Deserialize(reader);
            }

Using the "System.Xml.Serialization" namespace

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM