Десериализация C # xml не будет выделять дочерние элементы в список

#c# #.net #xml #deserialization

#c# #.net #xml #десериализация

Вопрос:

Я не могу понять, почему это не работает, я искал ответ, и когда я суммирую все, это должно сработать, но почему-то этого не происходит. Итак, у меня есть класс Bill, который имеет некоторые свойства, которые десериализуются нормально, но у меня есть статьи списка свойств, которые появляются пустыми.

прошлое класса Bill

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

Класс изделия

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

Десериализация

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

Ответ №1:

Я использовал этот сайт https://json2csharp.com/xml-to-csharp вместе с предоставленным вами xml я могу просто отлично десериализовать коллекцию статей.

Вот сгенерированные классы:

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

 

И вот заполненный объект Articles :
введите описание изображения здесь

И вот код десериализации :

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

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

Использование пространства имен «System.Xml.Serialization»

Комментарии:

1. спасибо за предоставленный вами код и некоторую адаптацию, я получил то, что хотел

Ответ №2:

Вы пробовали использовать XmlTextReader вместо XmlReader? Это может вам помочь.