繁体   English   中英

列出子元素的属性

[英]Listing atributes from sub-elements

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

我要这样做的是将name属性加载到itemlistbox中所选Adventure_path元素内的Adventure元素的itemlistbox(“ adventure 1”,“ adventure 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);
    }
}

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

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

您有两个问题:

  1. 在访问其后代之前,不检查selectedElement是否为null
  2. 您将在每个循环上添加selectedElement第一个Adventure元素(看看-而不是使用docs元素(这是Adventure),而是从selectedElement加载Element("adventure")

相反,您应该使用

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

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

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

或搭配XPath

var xpath = String.Format("//adventure_path[@Name='{0}']/adventure", selectedItem);
List<string> adventureNames = doc.XPathSelectElements(xpath)
                                 .Select(a => (string)a.Attribute("Name"))
                                 .ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM