2013-05-24 4 views
6

Я пытаюсь прочитать файл , который я хочу сделать для своей мамы. Так что в основном это то, что я хочу сделать:Как читать значения из XML-документа для создания ComboBox?

  1. A ComboBox, в котором будут показаны все растительные имена в 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 теперь может отображать названия овощей, но как я могу сделать 2-ой ComboBox читать рецепты?

+0

Вы должны поместить значения «картофель» и «морковь» в их собственный узел. Вам просто нужно уточнить свой процесс выбора, вы захватываете узел высокого уровня и распечатываете все внутри, а не используете более конкретный селектор для поиска определенных элементов. – SpaceBison

+0

В качестве альтернативы добавлению нового узла вы можете поместить растительное имя в качестве атрибута растительного узла. – Kobunite

ответ

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 из-за комментариев. Спасибо

+0

Такая же реструктуризация требуется, чтобы вытащить названия овощей в атрибуты/узлы. Элемент xml может содержать либо текст *, либо * один или несколько подэлементов; он не может содержать оба. – Phylogenesis

+0

@ Филогенез. Вы можете иметь элементы, которые содержат как текст, так и другие элементы. Это называется * смешанным контентом *. Хорошим примером этого является XHTML, где '

Hello Mr X

' является действительным XML. –

+0

@Tragedian Вы правы, но в этом случае смешанный контент создает ужасную структуру. – Phylogenesis

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); 
} 
1

Я предполагаю, что вы используете C# в 4.0 рамках .Net

Вы можете отформатировать 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` 
Смежные вопросы