如何从XML文档中读取值以构建ComboBox?

时间:2013-05-24 08:46:00

标签: c# xml winforms

我正在尝试阅读我想为我妈做的文件。基本上这就是我想要做的事情:

  1. 一个ComboBox,它将显示XML中的所有蔬菜名称。
  2. 选择蔬菜后,第二个ComboBox将在XML中显示食谱名称,该名称可以使用在第一个ComboBox中选择的蔬菜进行烹饪。
  3. 最后,如果确定Button,所选配方将读取通往配方的文件路径。
  4. 我写的

    XML

    <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#代码

    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.
    }
    

    第一个ComboBox现在能够显示蔬菜名称,但如何让第二个ComboBox阅读食谱?

3 个答案:

答案 0 :(得分:1)

您的xml应该重新构建,因为在将配方名称和文件路径节点作为配方节点的值时混合数据

这是一种更好的方法:

<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>

因此,要显示需要提取配方节点属性的配方。 如何执行此操作在此处说明:How to read attribute value from XmlNode in C#?

编辑:由于评论而修正了xml结构。感谢

答案 1 :(得分:1)

如果您希望能够从文档中获取蔬菜的名称,最简单的方法是将其定义为自己独立的数据。关于你所做的事情,没有什么无效,但这使得获取你想要的数据变得非常困难。

如果可以,可以将结构更改为类似的内容,以便让您的生活更轻松:

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

假设您使用的是.NET 3.5或更高版本,您将可以访问LINQ-to-XML API。这些提供了一种从XML文档中读取值的简化方法,并且应该可以更轻松地解决这个问题。

使用以下方法创建文档:

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

然后你可以编写一个查询来获取这样的蔬菜元素:

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

获得这些元素后,您可以获得他们的名字,如下所示:

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

然后,您可以非常轻松地将此信息插入到您的组合框中:

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

答案 2 :(得分:1)

我假设你在.Net 4.0框架中使用C#

您可以像这样格式化xml:

<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>

然后使用此查询选择这些项目:

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();

然后是你的班级结构:

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`