I'm trying to read an xml file which I want to make for my mom. So basically this is what I want to do:
ComboBox
which will show all the vegetable names in the XML.ComboBox
will show the recipe names in the XML that could use the vegetable selected in the first ComboBox
for cooking.Button
, the selected recipe will read the file path which leads to the recipe.<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>
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
is now able to display the vegetable names, but how do I make the 2nd ComboBox
to read the recipes?
Your xml should be restructured, as you are mixing data when putting recipe names and file path node as the value of the recipe node
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 attribute of the recipe node. How to do this is explained here: How to read attribute value from XmlNode in C#?
Edit: Corrected xml structure due to comments. Thanks
If you want to be able to get the name of a vegetable out of the document, the easiest thing to do is to define it as its own separate piece of data. There's nothing invalid about what you've done, but it's made it quite a lot harder to get to the data you want.
If you could can, change the structure to something like this, so that it makes 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're using .NET 3.5 or newer, you will have access to the LINQ-to-XML APIs. These provide a simplified way to to read values from an XML document and should make solving this problem a little easier.
You create a document using:
var document = XDocument.Load("Recipe_List.xml");
Then you can write a query to get the vegetable elements like this:
var vegetables = document
.Element(XName.Get("vegetables"))
.Elements(XName.Get("vegetable"));
Once you have these elements, you can get their names, like this:
var vegNames = vegetables.Select(ele => ele.Element(XName.Get("name")).Value);
You can then plug this information into your combo-box really easily:
foreach (string name in vegNames)
{
comboBox1.Items.Add(name);
}
I assume, you're using C# in .Net 4.0 framework
You can format your xml like this:
<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 those items:
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`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With