LINQ:如何返回所有子元素?

时间:2012-06-13 05:09:03

标签: c# xml linq

对于我正在处理的应用程序,我必须显示XML文件中的数据。正在进行一些转换,但最终结果将显示在树视图中。当用户点击某个节点时,我想在列表视图中弹出详细信息。

当没有选择节点时,我基本上使用LINQ来获取我遇到的第一个项目的细节。

这是我的XML的简化版本

<root>
   <parent label="parent1">
      <child label="child1">
         <element1>data</element1>
         <element2>data</element2>
         ...
      </child>
      <child label="child2">
         <element1>data</element1>
         <element2>data</element2>
         ...
      </child>
   </parent>
</root>

以下是用于获取它的代码(在选择了通过XPAthSelectStatement设置树视图的父节点之后):

protected void listsSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    XElement rootElement = XElement.Load(MapPath(TreeSource.DataFile));
    rootElement = rootElement.XPathSelectElement("//parent[@label='parent1']");
    XElement parentElement;

    parentElement = rootElement;

    var query = (from itemElement in parentElement.Descendants("child")
                 select new
                 {
                     varElement1 = itemElement.Element("element1").Value,
                     varElement2 = itemElement.Element("element2").Value,
                     ...
                 }).Take(1);

    e.result = Query;
}

这是一种享受,我可以从那里读出varElement1varElement2值。但是,当我尝试为用户实际选择节点时实现类似的机制时,我似乎碰到了一堵墙。

我的方法是使用另一个XPatchSelectStatement来到实际节点:

parentElement = rootElement.XPathSelectElement("//child[@label='" + tvwChildren.SelectedNode.Text + "']");

但我有点难以理解如何构建适当的LINQ查询来读取嵌套在子节点下的所有元素。我尝试使用parentElement.Elements(),但这产生了错误。我还查看了使用Nodes(),但结果相似。

我想我可以使用foreach循环来访问节点,但是我不知道如何将结果放到LINQ查询中,这样我就可以返回相同的e.Result = query

我对LINQ很新,正如您可能已经猜到的那样,所以任何提示都会非常受欢迎。

4 个答案:

答案 0 :(得分:1)

我认为在这种情况下数据绑定会更容易。

XDocument doc = XDocument.Load(filePath);
if (doc.Root == null)
{
throw new ApplicationException("invalid data");
}
tvwChildren.Source=doc;

但是如果你想以这种方式希望跟随一个有帮助(不是确切的解决方案)

XElement root = XElement.Load("Employees.xml");
TreeNode rootNode = new TreeNode(root.Name.LocalName);
treeView1.Nodes.Add(rootNode);
    foreach(XElement employee in root.Elements())
           {
            TreeNode employeeNode = new TreeNode("Employee ID :" + employee.Attribute("employeeid").Value);
            rootNode.Nodes.Add(employeeNode);
                 if (employee.HasElements)
                 {
                    foreach(XElement employeechild in employee.Descendants())
                     {
                        TreeNode childNode = new TreeNode(employeechild.Value);
                        employeeNode.Nodes.Add(childNode);
                     }
                 }
            }

您可以尝试使用Resharper工具来创建更好的linq语句。它显示了可能的,您可以轻松地将每个for,foreach循环转换为linq语句。

答案 1 :(得分:1)

这是为您提供子元素的查询(假设只有一个具有指定标签的child元素):

var childElement = rootNode.Descendants("child")
                           .Single(e=>e.Attribute("label").Value == "child1");

如果您有多个child元素与label="child1"但这些元素位于不同的parent元素下,您可以使用相同的方法首先获取parent元素,然后是child元素。

完成上述操作后,您可以使用此查询获取element节点下的所有child个节点:

var elements = childElement.Descendants().Select(e=>e.Value);

答案 2 :(得分:0)

我不完全确定我明白你要做什么,但听起来可能就是这样:

var data =
    from p in xml.Root.Elements("parent")
    where p.Attribute("label").Value == "parent1"
    from c in p.Elements("child")
    where c.Attribute("label").Value == "child2"
    from d in c.Elements()
    select d.Value;

如果有帮助,请告诉我。

答案 3 :(得分:0)

使用this Xml library,您可以编写XPath,如:

XElement child = rootElement.XPathElement(
    "//parent[@label={0}]/child[@label={1}]", "parent1", "child2");