列出子元素的属性

时间:2013-12-08 10:02:33

标签: c# xml

我是C#的新手,但我正在尝试从xml文件加载数据,就像这样......

<?xml version="1.0" encoding="utf-8" ?> 
<adventures>
  <adventure_path Name ="Adventure Path 1">
    <adventure Name ="Adventure 1">
      <senario Name ="Senario 1">
        <location Name="Location 1" Players="1"/>
      </senario>

    <adventure Name ="Adventure 2">
      <senario Name ="Senario 2">
        <location Name="Location 2" Players="1"/>
      </senario>
    </adventure>
  </adventure_path>

  <adventure_path Name ="Adventure Path 2">
    <adventure Name ="Adventure 3">
      <senario Name ="Senario 3">
        <location Name="Location 3" Players="1"/>
      </senario>

    <adventure Name ="Adventure 4">
      <senario Name ="Senario 4">
        <location Name="Location 4" Players="1"/>
      </senario>
    </adventure>
  </adventure_path>
</adventures>

我正在尝试做的是将名称属性加载到项目列表框中所选adventure_path元素中冒险元素的项目列表框(“冒险1”,“冒险2”等)。我让选择部分工作,并加载到列表工作。什么不起作用是加载所有的冒险......

基本上会发生什么是ListBox1加载冒险路径都很好和花花公子,我选择了一个所说的冒险路径,而ListBox2加载了第一次冒险......就是这样。它不会加载冒险2,3或4.所以这里的代码应该加载所有的冒险 -

private void lst_Adventure_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string selectedItem = lst_Adventure.SelectedItem.ToString();

    lst_Adventures.Items.Clear();

    XDocument doc = new XDocument();
    bool gotStatsXml = false;
    try
    {

        doc = XDocument.Load("D:\\WpfApplication1\\WpfApplication1\\Adventures.xml");
        gotStatsXml = true;
    }
    catch
    {
        gotStatsXml = false;

    }

    XElement selectedElement = doc.Descendants().Where(x => (string)x.Attribute("Name") == selectedItem).FirstOrDefault();

    foreach (var docs in selectedElement.Descendants("adventure")) ;
    {
        XElement elements = selectedElement.Element("adventure");

        string AdventuresPathName = elements.Attribute("Name").Value;

        lst_Adventures.Items.Add(AdventuresPathName);
    }
}

2 个答案:

答案 0 :(得分:0)

您缺少值属性x.Attribute(“名称”)。Value

 XElement selectedElement = doc.Descendants().Where(x => x.Attribute("Name").Value == selectedItem).FirstOrDefault();

答案 1 :(得分:0)

你有两个问题:

  1. 在访问其后代之前,您不会检查selectedElement是否为空
  2. 您要在每个循环中添加selectedElement的第一个冒险元素(看看 - 而不是使用docs元素(冒险),您从{{1}加载Element("adventure") })
  3. 相反,你应该使用

    selectedElement

    或者,只需获取所有冒险名称:

    if (selectedElement != null)
    {
       foreach (var docs in selectedElement.Elements("adventure")) 
       {
           string AdventuresPathName = (string)docs.Attribute("Name");
           lst_Adventures.Items.Add(AdventuresPathName);
       }
    }
    

    或者使用XPath

    List<string> adventureNames =
             doc.Root.Elements("adventure_path")
                .Where(ap => (string)ap.Attribute("Name") == selectedItem)
                .Elements("adventure")
                .Select(a => (string)a.Attribute("Name"))
                .ToList();