How to read values ​​from an XML document to create a ComboBox?

I am trying to read an xml file that I want to make for my mom. So basically this is what I want to do:

  • A ComboBox in which all plant names in XML will be displayed.
  • After selecting vegetables, the second ComboBox display the recipes names in XML, which can use the vegetable selected in the first ComboBox for cooking.
  • Finally, with OK Button selected recipe will read the path to the file that leads to the recipe.

XML I wrote

 <Vegetables> <vegetable name="Carrot"> <recipe name="ABCrecipe"> <FilePath>C:\\</FilePath> </recipe> <recipe name="DEFrecipe"> <FilePath>D:\\</FilePath> </recipe> </vegetable> <vegetable name="Potato"> <recipe name="CBArecipe"> <FilePath>E:\\</FilePath> </recipe> <recipe name"FEDrecipe"> <FilePath>F:\\</FilePath> </recipe> </vegetable> </Vegetables> 

C # code

 private void Form1_Load(object sender, EventArgs e) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("Recipe_List.xml"); XmlNodeList vegetables = xDoc.GetElementsByTagName("Vegetable"); for (int i = 0; i < vegetables.Count; i++) { comboBox1.Items.Add(vegetables[i].Attributes["name"].InnerText); } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { //I'm lost at this place. } 

The first ComboBox can now display the names of vegetables, but how to make the 2nd ComboBox to read recipes?

+6
source share
3 answers

Your xml should be restructured as you mix the data when entering the names of the recipes and the path to the node file as the value of the node recipe

Here is a better approach:

 <Vegetables> <vegetable name="Carrot"> <recipe name="ABCrecipe"> <FilePath>C:\\</FilePath> </recipe> <recipe name="DEFrecipe"> <FilePath>D:\\</FilePath> </recipe> </vegetable> <vegetable name="Potato"> <recipe name="CBArecipe"> <FilePath>E:\\</FilePath> </recipe> <recipe name="FEDrecipe"> <FilePath>F:\\</FilePath> </recipe> </vegetable> </Vegetables> 

So, to display the recipes, you need to extract the node recipe attribute. How to do this is explained here: How to read attribute value from XmlNode in C #?

Edit: Fixed xml structure due to comments. Thanks

+1
source

If you want to get the name of a vegetable from a document, the easiest way is to define it as a separate separate piece of data. There is nothing invalid about what you did, but it made it much harder to get the data you need.

If you could, change the structure to something like this to make your life easier:

 <vegetables> <vegetable> <name>Carrot</name> <recipe> <name>ABCrecipe</name> <path>C:\\</path> </recipe> <recipe> <name>DEFrecipe</name> <path>D:\\</path> </recipe> </vegetable> </vegetables> 

Assuming you are using .NET 3.5 or later, you will gain access to the LINQ-to-XML API. They provide a simplified way to read values ​​from an XML document and should make it easier to solve this problem.

You create a document using:

 var document = XDocument.Load("Recipe_List.xml"); 

Then you can write a query to get plant elements like this:

 var vegetables = document .Element(XName.Get("vegetables")) .Elements(XName.Get("vegetable")); 

After you have these elements, you can get their names, for example:

 var vegNames = vegetables.Select(ele => ele.Element(XName.Get("name")).Value); 

You can easily connect this information to your combo-box:

 foreach (string name in vegNames) { comboBox1.Items.Add(name); } 
+1
source

I assume you are using C # in .Net 4.0 environment

You can format your XML address as follows:

 <Vegetables> <vegetable> <name>Carrot</name> <recipe> <name>ABCrecipe</name> <FilePath>C:\\</FilePath> </recipe> <recipe> <name>DEFrecipe</name> <FilePath>D:\\</FilePath> </recipe> </vegetable> <vegetable> <name>Potato</name> <recipe> <name>CBArecipe</name> <FilePath>E:\\</FilePath> </recipe> <recipe> <name>FEDrecipe</name> <FilePath>F:\\</FilePath> </recipe> </vegetable> </Vegetables> 

Then just use this query to select these elements:

 var vegiesList = (from veg in xDoc.Descendants("vegetable") select new Vegetable() { Name = veg.Element("name").Value, Recipes = (from re in veg.Elements("recipe") select new Recipe(re.Element("name").Value, re.Element("FilePath").Value)).ToList() }) .ToList(); 

Then for your class structure:

 class Vegetable { public string Name { get; set; } public List<Recipe> Recipes { get; set; } } class Recipe { public Recipe(string name, string path) { Name = name; Path = path; } public string Name { get; set; } public string Path { get; set; } } vegiesList.ForEach(veg => comboBox1.Items.Add(veg.Name)); //You can select its property here depending on what property you want to add on your `ComboBox` 
+1
source

Source: https://habr.com/ru/post/945755/


All Articles