3

对于我正在处理的应用程序,我必须显示 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(),但这会产生错误。我也看过 using Nodes(),但结果相似。

我想我可以使用 foreach 循环来访问节点,但是我不确定如何将结果放入 LINQ 查询中,以便可以返回相同的结果e.Result = query

正如您可能已经猜到的那样,我对 LINQ 相当陌生,因此非常感谢任何提示。

4

4 回答 4

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 语句。

于 2012-06-13T05:56:14.770 回答
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);
于 2012-06-13T07:16:22.243 回答
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;

让我知道这是否有帮助。

于 2012-06-13T08:39:26.403 回答
0

使用这个 Xml 库,您可以编写您的 XPath,如下所示:

XElement child = rootElement.XPathElement(
    "//parent[@label={0}]/child[@label={1}]", "parent1", "child2");
于 2012-06-13T17:55:12.660 回答