Search code examples
c#xmlchildren

Specific xml child based on combobox selected item


This may be a duplicate, but I haven't been able to find a solution.

I have a ComboBox that is populated from an xml file. When I select an item in the ComboBox I want to populate a listBox with the "Special" elements from that same xml file.

xml:

 <ClassID Barbarian="Barbarian">
    <Name>Barbarian</Name>
    <Alignment>NG CG NN CN NE CE</Alignment>
    <Special>Fast Movement</Special>
    <Special>Rage Power</Special>
 </ClassID>

I can get the listBox to populate with ALL the "Special" elements, but I only want the ones for the specified class name (i.e. Barbarian attribute).

Code to populate listBox with ALL the "Special" elements, regardless of what ComboBox item is selected:

//Gets Specials from xml
public static List<string> GetSpecialsFromXml(string filename, string tagname)
{
    List<string> Specials = new List<string>();
    XmlDocument doc = new XmlDocument();
    
    doc.Load(filename);
   
    XmlNodeList specials = doc.GetElementsByTagName(tagname);

    foreach(XmlNode special in specials)
    {
        Specials.Add(special.InnerText);
    }
    return Specials;
}

//Loads feats into feat list
public void LoadFeats()
{
    List<string> Special = GetSpecialsFromXml(Gamepath, "Special");
    FeatBox.Items.AddRange(Special.ToArray());
}

LoadFeats is called with the ComboBox SelectedItemChanged event.

I am still a noob when working with xml files.

Edit: TL;DR solution:

Changed public static List<string> GetSpecialsFromXml(string filename, string tagname) to public List<string> GetSpecialsFromXml(string filename, string tagname).

Added string Combo = ComboBox.Text; and string strXPath = $"ClassID[{Combo}='{Combo}']/Special"

Replaced XmlNodeList specials = doc.GetElementsByTagName(tagname); with XmlNodeList specials = doc.SelectNodes( strXPath );


Solution

  • Instead of looking for "tagname", with doc.GetElemnetByTagName, use XPath in a SelectNodes() function call. XPath is to XML what SQL is to a database, and is very powerful.

    Use an XPath statement like in a "SelectNodes()" call

    string strXPath= "//ClassID[@Barbarian='Barbarian']/Special"
    

    Replace your XmlNodeList specials = doc.GetElementsByTagName(tagname); with this

    XmlNodeList specials = doc.SelectNodes( strXPath );
    

    Then iterate away like you're already doing.

    Good Luck with your project