Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
79 views
in Technique[技术] by (71.8m points)

Deserialization xml on Multiple Child c#

I have a list of Invoice and I have to deserializate it. First I serialized to xml and it ways easy to find and apply. This time I can not deserializate the Item lists in the xml. For example, this is my xml serialized row:

<?xml version="1.0" encoding="utf-8"?>
 <Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Invoice>4711</Invoice>
   <Table>8</Table>
   <Outlet>3</Outlet>
   <User>17</User>
   <Creation>20140101</Creation>
   <Item>
     <Type>Revenue</Type>
     <Productgroup>5</Productgroup>
     <TotalAmount>6</TotalAmount>
     <TaxClassification>1</TaxClassification>
     <Text>Pizza Tonna</Text>
   </Item>
   <Item>
     <Type>Gratuity</Type>
     <TotalAmount>1.5</TotalAmount>
     <Text>Tip</Text>
   </Item>
   <Item>
     <Type>Payment</Type>
     <TotalAmount>7.5</TotalAmount>
     <ResNo>4812</ResNo>
   </Item>
 </Body>

As you see, I have a Body root xml and 5 mainly row but in the deep I have more than one Item data which is a list. If I had one item for each Invoice, it would be easy to do but during tough researches, I could not get any point.

Let me sahre with you what I did. These are my Body and Item Classes:

[XmlRoot("Body")]
public class Body
{
    [XmlElement("Invoice")]
    public int Invoice { get; set; }

    [XmlElement("Table")]
    public int Table { get; set; }

    [XmlElement("Outlet")]
    public int Outlet { get; set; }

    [XmlElement("User")]
    public int User { get; set; }

    [XmlElement("Creation")]
    public int Creation { get; set; }

    [XmlElement("Item")]
    public List<Item> Items { get; set; }

}

[XmlRoot("Item")]
public class Item
{
    
    [XmlElement("Type")]
    public string? Type { get; set; }

    [XmlElement("Productgroup")]
    public int? Productgroup { get; set; }
    public bool ShouldSerializeProductgroup()
    {
        return Productgroup.HasValue;
    }

    [XmlElement("TotalAmount")]
    public double? TotalAmount { get; set; }
    public bool ShouldSerializeTotalAmount()
    {
        return TotalAmount.HasValue;
    }

    [XmlElement("TaxClassification")]
    public double? TaxClassification { get; set; }
    public bool ShouldSerializeTaxClassification()
    {
        return TaxClassification.HasValue;
    }

    [XmlElement("Text")]
    public string? Text { get; set; }
    
    [XmlElement("ResNo")]
    public int? ResNo { get; set; }
    public bool ShouldSerializeResNo()
    {
        return ResNo.HasValue;
    }
}

And here is my main program for serialization and nice versa.

static void Main(string[] args)
    {
        try
        {
            Body body = new Body 
            { 
                Invoice = 4711, 
                Table = 8 / 1, 
                Outlet = 3, 
                User = 17, 
                Creation = 20140101,
                Items = new List<Item>()
                {
                    new Item{Type="Revenue",Productgroup = 5,TotalAmount=6.00,TaxClassification=1,Text="Pizza Tonna"},
                    new Item{Type="Gratuity",TotalAmount=1.50,Text="Tip"},
                    new Item{Type="Payment",TotalAmount=7.50,ResNo=4812}
                }
            };
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Body));
            StreamWriter sw = new StreamWriter("CloseInvoice.xml");
            xmlSerializer.Serialize(sw, body);
            sw.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        try
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Body));
            StreamReader sr = new StreamReader("CloseInvoice.xml");
            Body body = (Body)xmlSerializer.Deserialize(sr);
            Console.WriteLine("Invoice Information");
            Console.WriteLine("Type: "+body.Invoice);
            Console.WriteLine("Table: " + body.Table);
            Console.WriteLine("Outlet: " + body.Outlet);
            Console.WriteLine("User: " + body.User);
            Console.WriteLine("Creation: " + body.Creation);
        }
        catch (Exception)
        {

            throw;
        }
    }

I tried all loops but I cannot write the Items on the console. Can you please help me? Thank from now.

Edit: Here is my console out. I can get Body Rows but I want to get Item List in the xml too.

enter image description here

question from:https://stackoverflow.com/questions/65833608/deserialization-xml-on-multiple-child-c-sharp

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Well, It seems you're interested in just looping through the Body.Items collection here. So, I think @Pierre Michel's covers that.

However, given your comments, I want to extend on that answer by including the use of Reflection with PropertyInfo of the type Item.

My answer will showcase conditionally checking for the existence of a value being specified. (i.e. when not null as a reference type, and not the default value when a value type.

For each PropertyInfo in each instance of Item, we'll do a conditional check on whether that Property is null or default, and we'll perform a Console.Write when a value is determined to exist and be specified (and not default).

Note we'll include using System.Reflection; in the file.


    foreach (var item in body.Items)
    {
        WriteItemPropertiesThatHaveValues(item);
    }


    void WriteItemPropertiesThatHaveValues<T>(T item)
    {
        foreach (PropertyInfo pi in typeof(Item).GetProperties())
        {
            WriteItemPropertyThatHasValue(item, pi);
        }
        Console.WriteLine();
    }

    void WriteItemPropertyThatHasValue<T>(T item, PropertyInfo pi)
    {
        T defaultTValue = default;
        var itemValue = pi.GetValue(item);

        if (!(itemValue?.Equals(defaultTValue) ?? true))
            Console.WriteLine($"{pi.Name} => { itemValue }");
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...