通过Linq获取父节点的属性值到XML

Get attribute value of parent node by Linq to XML

我在使用 Linq to XML 解析 XML 文件时遇到问题。

我的 XML 结构如下:

<Module>
  <Variable Name="Variable1" Value="True" />
  <Variable Name="Variable2" Value="True" />
  <Variable Name="Variable3" Value="True" />
  </Task>
  <Task Name="Task1">
    <Variable Name="Task1Variable1" Value ="True" />
    <Variable Name=" Task1Variable2" Value ="True" />
  </Task>
  <Task Name="Task2">
    <Variable Name="Task2Variable1" Value ="True" />
    <Variable Name=" Task2Variable2" Value ="True" />
  </Task>
</Module>

我打算做的是获取每个变量名称属性的值。 因此,对于直接位于节点模块下的元素,它可以很好地与

var variables = (from cfg in _xElements.Descendants("Module").Elements("Variable")
                                       select cfg.Attribute("Name"));

问题始于任务节点下的变量名称属性,因为我还需要有关任务名称的信息。

所以我想得到的是变量名的信息加上作为变量元素父节点的任务名的信息。

有没有办法使用 Linq 完成此操作?

您可以使用 XElement

的父级 属性
var variables = (from cfg in _xElements.Descendants("Variable")
                                       select new
{
  TaskName = cfg.Parent.Name == "Task"? cfg.Parent.Attribute("Name"):null,   
  VariableAttribute = cfg.Attribute("Name")
});

您当前代码的问题在于您使用的是 Elements it is returning only the Variable which are direct child of root node. Use Descedants

此查询将为您提供预期的输出:-

 var variables = (from cfg in _xElements.Descendants("Variable")
                  select cfg.Attribute("Name"));

Check difference between Elements and Descendants.

后代在这种情况下不起作用。尝试完整的解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = 
                "<Module>" +
                  "<Variable Name=\"Variable1\" Value=\"True\" />" +
                  "<Variable Name=\"Variable2\" Value=\"True\" />" +
                  "<Variable Name=\"Variable3\" Value=\"True\" />" +
                  "<Task Name=\"Task1\">" +
                    "<Variable Name=\"Task1Variable1\" Value =\"True\" />" +
                    "<Variable Name=\"Task1Variable2\" Value =\"True\" />" +
                  "</Task>" +
                  "<Task Name=\"Task2\">" +
                    "<Variable Name=\"Task2Variable1\" Value =\"True\" />" +
                    "<Variable Name=\"Task2Variable2\" Value =\"True\" />" +
                  "</Task>" +
                "</Module>";

            XDocument doc = XDocument.Parse(xml);

            var results = doc.Elements("Module").Select(m => new {
                variables = m.Elements("Variable").Select(n => new {
                   name = (string)n.Attribute("Name"),
                   value = (string)n.Attribute("Value")
                }).ToList(),
                tasks = m.Elements("Task").Select(o => new {
                    name = (string)o.Attribute("Name"),
                    variables = o.Elements("Variable").Select(p => new {
                        name = (string)p.Attribute("Name"),
                        value = (string)p.Attribute("Value")
                    }).ToList()
                }).ToList()
            }).FirstOrDefault();
        }
    }
}