Home > Back-end >  Deserialize XML same items with different tag
Deserialize XML same items with different tag

Time:10-11

This is an XML example I want to deserialize and use in a Desktop App, where the user could insert an XML like this one:

   <Settings>
        <FileName>C:\Users\myniceuser\Desktop\hello.xmldoc</FileName>
        <Zones>
                <Row1>
                        <Address>2</Address>strong text
                        <Zone>2</Zone>
                        <Installed>True</Installed>
                </Row1>
                <Row2>
                        <Address>3</Address>
                        <Zone>2</Zone>
                        <Installed>True</Installed>
                </Row2>
                <Row3>
                        <Address>4</Address>
                        <Zone>2</Zone>
                        <Installed>True</Installed>
                </Row3>
                <Row4>
                        <Address>5</Address>
                        <Zone>2</Zone>
                        <Installed>True</Installed>
                </Row4>
        </Zones>
        <Network_IP>010.000.008.072</Network_IP>
        <Ethernet_Enable>true</Ethernet_Enable>
        <Language>1</Language>
</Settings>

The class I implemented is this one:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace MyApp.Models
{
    [XmlRoot(ElementName = "Settings")]
    public class XML_Settings
    {

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


        //[XmlElement(ElementName = "Zones")]
        [XmlElement(ElementName ="Zones")]
        public Zones_Points[] Zones_Points { get; set; }

        [XmlElement(ElementName = "Network_IP")]
        public string NetworkIP { get; set; }

        [XmlElement(ElementName = "Ethernet_Enable")]
        public bool EthernetEnable { get; set; }

        [XmlElement(ElementName = "Language")]
        public int Language { get; set; }
}
    [XmlRoot(ElementName = "")]
    public partial class Zones_Points
    {
        [XmlElement(ElementName ="Address")]
        public int Address { get; set; }

        [XmlElement(ElementName ="Zone")]
        public int PointZone { get; set; }

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

}
}

I deserialize like this:

Models.XML_Settings inputted_xml = new();
using StreamReader stream_xml = new StreamReader(xmlfile_path, CodePagesEncodingProvider.Instance.GetEncoding(1253));
                
XmlSerializer serializer = new XmlSerializer(typeof(Models.XML_Settings));

try
{
 Models.XML_Settings input = (Models.XML_GR6500)serializer.Deserialize(stream_xml);
 }
 catch (Exception exception)
 {
 MessageBox.Show(exception.Message);
 }

I want my app to input files in XML like this one, and convert their data to a class that i can use.

The object "input" created by the Deserialization got every data correct, except the Zones, those that in XML have the "Row" tags. Those "rows" could every time be more or less that 4.

What can I do to have the items with the row tags deserialized and inputted into a Zones_Points list or array?

CodePudding user response:

Use IXmlSerializable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(XML_Settings));
            XML_Settings settings = (XML_Settings)serializer.Deserialize(reader);
  
        }
    }
    [XmlRoot("Settings")]
    public class XML_Settings
    {


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

        [XmlElement(ElementName = "Zones")]
        public Zones_Points Zones_Point { get; set; }
        [XmlElement(ElementName = "Network_IP")]
        public string NetworkIP { get; set; }
        [XmlElement(ElementName = "Ethernet_Enable")]
        public bool EthernetEnable { get; set; }
        [XmlElement(ElementName = "Language")]
        public int Language { get; set; }
    }
    public partial class Zones_Points : IXmlSerializable
    {
        // Xml Serialization Infrastructure
        [XmlElement(ElementName = "Zones")]
        public List<Zones_Point> Points { get; set; }

        public void WriteXml(XmlWriter writer)
        {
        }

        public void ReadXml(XmlReader reader)
        {

            XElement zones = (XElement)XElement.ReadFrom(reader);
            Points = new List<Zones_Point>();
            foreach (XElement row in zones.Elements())
            {
                Zones_Point Point = new Zones_Point();
                Points.Add(Point);
                Point.Address = (int)row.Element("Address");
                Point.PointZone = (int)row.Element("Zone");
                Point.Installed = (Boolean)row.Element("Installed");
            }

        }

        public XmlSchema GetSchema()
        {
            return (null);
        }
    }
    public partial class Zones_Point
    {
        [XmlElement(ElementName = "Address")]
        public int Address { get; set; }
        [XmlElement(ElementName = "Zone")]
        public int PointZone { get; set; }
        [XmlElement(ElementName = "Installed")]
        public bool Installed { get; set; }
    }
}
  • Related