6

我正在尝试读取我想为我妈妈制作的所以基本上这就是我想要做的:

  1. AComboBox将显示 XML 中的所有蔬菜名称。
  2. 选择蔬菜后,第二个ComboBox将在 XML 中显示食谱名称,可以使用第一个中选择的蔬菜ComboBox进行烹饪。
  3. 最后,点击 OK Button,所选配方将读取指向该配方的文件路径。

我写的 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阅读食谱?

4

3 回答 3

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);
}
于 2013-05-24T09:19:16.120 回答
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`
于 2013-05-24T09:22:23.473 回答
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 结构。谢谢

于 2013-05-24T08:50:15.190 回答