MeowMeow
MeowMeow

Reputation: 95

How to read the attribute of a child node within a node?

I'm trying to read an file and I want to do this:

  1. A ComboBoxwhich will show all the vegetable names in the .
  2. After selecting a vegetable, the second ComboBox will show the recipe names in the that could use the vegetable selected in the first ComboBox for cooking.
  3. Last, with a OK button, the selected recipe will read the file path which 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

public Form1()
{
    InitializeComponent();            
    xDoc.Load("Recipe_List.xml");
}

XmlDocument xDoc = new XmlDocument();

private void Form1_Load(object sender, EventArgs e)
{
    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 according to the file?

Upvotes: 1

Views: 257

Answers (2)

Saravanan
Saravanan

Reputation: 7844

You can build the following Xpath and then get the recipe for the vegetable

string xpath = string.Format("//vegetable[@name='{0}']/recipe",comboboxSelectedItem);
var selectedVegetableRecipe = xdoc.SelectSingleNode(xpath);

However, as Ondrej Tucny pointed out, during the application start you can cache the xml document in a static XMLDocument and then use it the code to avoid performance overhead for each call.

Upvotes: 2

Ondrej Tucny
Ondrej Tucny

Reputation: 27974

First of all, you aren't storing the parsed XML anywhere. Hence in comboBox1_SelectedIndexChanged you can't work with it. You should introduce a private field (or property, whatever) in your form instead of the xDoc local variable.

If you for some odd reason wanted to keep going the way you are working with the XML file right now, you would have to lookup the selected <vegetable> element in comboBox1_SelectedIndexChanged and then process all its child <recipe> elements. However, this is unnecessarily complicated. Better way is to start with declaring the data structure and use XML serialization.

You will end up with two classes, Vegetable and Recipe, and use XmlSerializer to serialize (store into XML) and deserialize (read from XML) you data. In the form you will then work with objects and don't have to play with XML manually.

Upvotes: 0

Related Questions