Read a part of XML file into a table

Raymond Gilbers 176 Reputation points

Hello All,

I'm able to read specific data from a XML file. But the way the file is set up and how I would like my program works I need to create (I think) something like a datatable or so. Unfortunately i'm not sure how to tackle this issue.

The XML file looks like this:


what I want is to read the machineprofile. And "connect" the machinename to a combobox. So in other words I want the combobox has the items mach 1, mach2 mach3 etc and when I selet a particular selection all specific items whith this machine will be displayed.
I'm able to read the XML that is not the issue I guess but I don't know how to tackle the next I need to make a new method or create a DataTable or so. I know how machine "Machines exsist" so I thought I create a kind of loop and place it in a method but that will not work I really think I have to place each data in a table. And the selection should have some kind of identity (e.g a number) which shows me later on all the info I want to see.

How can I do this?

private void openToolStripMenuItem_Click(object sender, EventArgs e)       
            using (OpenFileDialog ofd = new OpenFileDialog())  
                ofd.Filter =  "XML File (*.xml)|*.xml";  
                ofd.Title = "Open Client Profile File";  
                if (ofd.ShowDialog() == DialogResult.OK)  
                    _root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName);  
                    lblCompanyName.Text = _root.CompanyProfile.CompanyName;  
                    lblSiteName.Text = _root.CompanyProfile.SiteName;  
                    lblImo.Text = _root.CompanyProfile.Imo.ToString();  
                    lblMachineTotal.Text = _root.CompanyProfile.MachineTotal.ToString();  
                    lblClientNumber.Text = _root.CompanyProfile.ClientNumber.ToString();  
                    //Parse machine total to a machine total number.  
                    int counter = Int32.Parse(lblMachineTotal.Text);  

All the previous lables I'm able to read correctly but as you can see the Mach1 till 3 I would like to make vissible with selecting a selection in a combobox:


This combobox e.g. the top left one should show mach 1, mach 2 etc en selecting a particular one it should show all its relevant info. What should I do?

Maybe someone could give me some ideas.

Thanks in advance!

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,936 questions
0 comments No comments
{count} votes

Accepted answer
  1. Karen Payne MVP 35,011 Reputation points

    Unsure if this is what you are after. I setup a ComboBox DataSource to RootMachineProfile as a list. This means you have access to each property that can be data bound to controls. Classes were generated by Visual Studio paste special.

    For the ComboBox, no need to set DisplayMember.

    public class XmlOperations  
        public static Root Read()  
            const string fileName = @"XMLFile1.xml";  
            var xmlSerializer = new XmlSerializer(typeof(Root), new XmlRootAttribute { ElementName = "Root", IsNullable = true });  
            using (var fs = new FileStream(fileName, FileMode.Open))  
                return (Root)xmlSerializer.Deserialize(fs);  
    [XmlTypeAttribute(AnonymousType = true)]  
    [XmlRootAttribute(Namespace = "", IsNullable = false)]  
    public partial class Root  
        private RootCompanyProfile companyProfileField;  
        private RootMachineProfile[] machineProfileField;  
        public RootCompanyProfile CompanyProfile  
            get => companyProfileField;  
            set => companyProfileField = value;  
        public RootMachineProfile[] MachineProfile  
            get => machineProfileField;  
            set => machineProfileField = value;  
        public override string ToString() => $"{CompanyProfile.CompanyName}";  
    /// <remarks/>  
    [XmlTypeAttribute(AnonymousType = true)]  
    public partial class RootCompanyProfile  
        private string companyNameField;  
        private string siteNameField;  
        private uint imoField;  
        private int machineTotalField;  
        public string CompanyName  
            get => companyNameField;  
            set => companyNameField = value;  
        public string SiteName  
            get => siteNameField;  
            set => siteNameField = value;  
        public uint Imo  
            get => imoField;  
            set => imoField = value;  
        public int MachineTotal  
            get => machineTotalField;  
            set => machineTotalField = value;  
    [XmlTypeAttribute(AnonymousType = true)]  
    public partial class RootMachineProfile  
        private string machineNameField;  
        private uint serialNumberField;  
        private string typeNumberField;  
        private string typeField;  
        private ushort nominalSpeedField;  
        private byte frequencyField;  
        private ushort nominalPowerField;  
        public string MachineName  
            get => machineNameField;  
            set => machineNameField = value;  
        public uint SerialNumber  
            get => serialNumberField;  
            set => serialNumberField = value;  
        public string TypeNumber  
            get => typeNumberField;  
            set => typeNumberField = value;  
        public string Type  
            get => typeField;  
            set => typeField = value;  
        public ushort NominalSpeed  
            get => nominalSpeedField;  
            set => nominalSpeedField = value;  
        public byte Frequency  
            get => frequencyField;  
            set => frequencyField = value;  
        public ushort NominalPower  
            get => nominalPowerField;  
            set => nominalPowerField = value;  
        public override string ToString() => MachineName;  

    Form code

    var result = XmlOperations.Read();  
    List<RootMachineProfile> dataSource = result.MachineProfile.ToList();  
    comboBox1.DataSource = dataSource;  
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Raymond Gilbers 176 Reputation points

    Thank you very much for the detaild answer but (with all due respect) I hate copy paste I want to learn something from it. And i do not see what you have done that is not your fault but my lack of understanding C#

    You created a new Class ok.....untill that I understand but than i basically get lost but again thats probably my errror I appreciate a bit more help for the sake of learning

  2. Raymond Gilbers 176 Reputation points

    Thanks for all the great answers I will study the example code hat will help me

    0 comments No comments

  3. Raymond Gilbers 176 Reputation points

    I think I'm almost there but I don't understand one thing. The combobox get filled with different info as I expected and as the above example.

                        _root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName);  
                        lblCompanyName.ForeColor = Color.Black;  
                        lblCompanyName.Text = "Company Name: " + _root.CompanyProfile.CompanyName;  
                        lblSiteName.Text ="Sitename: " + _root.CompanyProfile.SiteName;  
                        lblImo.Text = "IMO: " + _root.CompanyProfile.Imo.ToString();  
                        lblMachineTotal.Text = "Machine Total: " + _root.CompanyProfile.MachineTotal.ToString();  
                        lblClientNumber.Text = "Clientnumber: " + _root.CompanyProfile.ClientNumber.ToString();  
                        _bindingSource.DataSource = _root.MachineProfiles.ToList();  
                        cmbMachineName.DataSource = _bindingSource;  
                        lblPower.DataBindings.Add("Text", _bindingSource, nameof(MachineProfile.NominalPower));  

    This is how I have done it. I created a list of the MachineProfiles and added that to the combobox. The result is what you see in below picture I dont understand why and what I do wrong.


    With debugging I can see that the databinding from the list worked out well (I guess)


    So I'm a bit confused cause I think I did exactly as @Karen Payne MVP suggested. Does anybody see where I go wrong?

  4. Jack J Jun 24,266 Reputation points Microsoft Vendor

    @Raymond Gilbers ,Welcome to Microsoft Q&A, I used a new method to show the related information in the form.

    First, I used the following code to convert the xml file to the datatable by using linq to xml.

     public DataTable GetDataTable(string file)  
                DataTable dt = new DataTable();  
                XDocument doc = XDocument.Load(file);  
                string[] arr = new string[7];  
                var result = doc.Descendants("CompanyProfile").First();  
                var dr = from n in doc.Descendants("MachineProfile")  
                         select new string[]{  
                         arr[0] = result.Element("Imo").Value,  
                         arr[1] = result.Element("MachineTotal").Value,  
                         arr[2] = n.Element("MachineName").Value,  
                         arr[3] = n.Element("Type").Value,  
                         arr[4] = n.Element("NominalSpeed").Value,  
                         arr[5] = n.Element("Frequency").Value,  
                         arr[6] = n.Element("NominalPower").Value,  
                foreach (var item in dr)  
                    dt.Rows.Add(item[0], item[1], item[2], item[3], item[4], item[5], item[6]);  
                return dt;  

    Second, we could use combobox_SelectedValueChanged event to load the related information from the selected item.

     private void MachineNamecmb_SelectedValueChanged(object sender, EventArgs e)  
                DataRow row = dt.Rows.Cast<DataRow>().Where(i => i.Field<string>("MachineName") == MachineNamecmb.SelectedItem.ToString()).First();  
                int index = dt.Rows.IndexOf(row);  
                txtImo.Text = dt.Rows[index]["Imo"].ToString();  
                txtFrequency.Text = dt.Rows[index]["Frequency"].ToString();  
                txtMachineTotal.Text= dt.Rows[index]["MachineTotal"].ToString();   
                txtType.Text= dt.Rows[index]["Type"].ToString();  
                txtNominalPower.Text= dt.Rows[index]["NominalPower"].ToString();  
                txtSpeed.Text = dt.Rows[index]["NominalSpeed"].ToString();  

    Third, Please use the following code to load the MachineName to the combobox in the button_click event.




    Best regards,

    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments