Search code examples
c#xmldatagridviewdatasetmulti-table

Multi-level xml in the DataSet and output to the dataGridView1 table


DataSet incorrectly outputs XML data to dataGridView1 due to the same names in the child tables.

here is my code...

 DataSet dataSet = new DataSet("Language");

 private void button1_Click_1(object sender, EventArgs e)
 {
     OpenFileDialog ofd = new OpenFileDialog();
     ofd.Filter = "XML|*.xml";
     if (ofd.ShowDialog() == DialogResult.OK)
     {
         try
         {
             List<string> listTableName = new List<string>();
             XmlReader xmlFile = XmlReader.Create(ofd.FileName, new XmlReaderSettings());
             dataSet.ReadXml(xmlFile);

             for (int i = 0; i <= dataSet.Tables.Count - 1; i++)
                 if (dataSet.Tables[i].ChildRelations.Count != 0)
                     comboBox1.Items.Add(dataSet.Tables[i].TableName); 

             dataGridView1.DataSource = dataSet.Tables[0].DefaultView;
             xmlFile.Close();

         }

         catch (Exception ex)
         {
             Console.WriteLine(ex);
         }
     }
 }

 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (comboBox1.SelectedIndex == 0)
         dataGridView1.DataSource = dataSet.Tables[comboBox1.SelectedIndex].DefaultView;
     else
         dataGridView1.DataSource = dataSet.Tables[comboBox1.Text].ChildRelations[0].ChildTable.DefaultView;
 }

here is the xml

<?xml version="1.0" encoding="utf-8"?>
<Language xmlns:dt="some-xml-namespace-here" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>English</Name>
  <Code>EN</Code>
  <Font>font_english</Font>
  <Reagents>
    <RecordReagent>
      <Key>Flour</Key>
      <Value>Flour</Value>
      <Unit>g</Unit>
    </RecordReagent>
    <RecordReagent>
      <Key>Milk</Key>
      <Value>Milk</Value>
      <Unit>ml</Unit>
    </RecordReagent>
  </Reagents>
  <Gases>
    <Record>
      <Key>Oxygen</Key>
      <Value>Oxygen</Value>
    </Record>
    <Record>
      <Key>CarbonDioxide</Key>
      <Value>Carbon Dioxide</Value>
    </Record>
    <Record>
      <Key>Nitrogen</Key>
      <Value>Nitrogen</Value>
    </Record>
  </Gases>
  <Actions>
    <Record>
      <Key>Reload</Key>
      <Value>Reload</Value>
    </Record>
        <Record>
      <Key>123124</Key>
      <Value>1323123</Value>
    </Record>
  </Actions>
  <ScreenSpaceToolTips />
</Language>

the problem is that the Gases and Actions table have the same Record table, and not their own. on Russian forums, I did not receive an answer on how to make it so that when choosing comboBox1 Gases, its Record table is selected and not the general one (while the code should be universal without specifying the table name)


Solution

  • https://i.imgur.com/5HF9GdD.png

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            
    
            if (comboBox1.SelectedIndex == 0)
                dataGridView1.DataSource = dataSet.Tables[comboBox1.SelectedIndex].DefaultView;
            else
            { 
    
                dataGridView1.DataSource = dataSet.Tables[comboBox1.SelectedItem.ToString()].ChildRelations[0].ChildTable.AsEnumerable().Where(o => o.Field<int?>(comboBox1.SelectedItem.ToString()+ "_Id") == 0).AsDataView();
    
            }
    
        }