【问题标题】:Not able to select relevant nested nodes: LINQ无法选择相关的嵌套节点:LINQ
【发布时间】:2013-09-20 07:07:57
【问题描述】:

我的示例 XML 是这样的:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <RoleSecurity Name="A" Workflowstatus ="B">
    <Accountgroup Name = "Group1">
      <Attribute ID="12345" Name="Sample1"/>
      <Attribute ID="12445" Name="Sample2"/>
    </Accountgroup>
    <Accountgroup Name = "Group2">
      <Attribute ID="12345" Name="Sample1"/>
      <Attribute ID="12445" Name="Sample2"/>
    </Accountgroup>
  </RoleSecurity>
</Root>

我正在尝试枚举和提取与特定角色名称、工作流状态和帐户组对应的所有 ID。

我的 LINQ 查询正在根据角色名称选择一个节点。但我无法进一步进行。 请帮忙!

这是我迄今为止的 LINQ 代码。

XElement xcd = XElement.Load(strFileName);
IEnumerable<XElement> enumCust = from cust in xcd.Elements("RoleSecurity")
           where (string)cust.Attribute("Name") == strRole
           select cust;

【问题讨论】:

标签: c# linq


【解决方案1】:

试试这个:

string roleName = "A";
string workflowStatus = "B";
string accountGroup = "Group1";

string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
    <Root>
        <RoleSecurity Name=""A"" Workflowstatus =""B"">
        <Accountgroup Name = ""Group1"">
            <Attribute ID=""12345"" Name=""Sample1""/>
            <Attribute ID=""12445"" Name=""Sample2""/>
        </Accountgroup>
        <Accountgroup Name = ""Group2"">
            <Attribute ID=""12345"" Name=""Sample1""/>
            <Attribute ID=""12445"" Name=""Sample2""/>
        </Accountgroup>
        </RoleSecurity>
    </Root>";

XElement element = XElement.Parse(xml);

var ids = element.Elements("RoleSecurity")
    .Where(
        e =>
            (string) e.Attribute("Name") == roleName &&
            (string) e.Attribute("Workflowstatus") == workflowStatus)
    .Elements("Accountgroup").Where(e => (string) e.Attribute("Name") == accountGroup)
    .Elements("Attribute")
    .Select(e => new {ID = (string) e.Attribute("ID"), Name = (string) e.Attribute("Name")});

【讨论】:

  • 非常感谢!奇迹发生了,代码正在运行! :) 关于.Element 函数的一个问题。您已经使用它来查询多个级别。这是如何工作的?
  • 我认为你误解了一些东西。起初,我使用Elements,它返回给定节点的IEnumerable&lt;XElement&gt;。仔细看看代码。代码通过过滤必要的内容逐层遍历。
  • 谢谢哈姆雷特...我意识到在每个“。”你深入一层。只是想知道,Descendant 方法有何不同?此解决方案已由另一位 SO 用户提供。需要用谷歌搜索。
  • Descendants 从当前级别返回任意级别的所有匹配节点。
【解决方案2】:

尝试使用这种方法,似乎与您的不同(在某些方面它确实发生了变化),但在我看来,这是一种流利地使用 LINQ 查询来解析 XML 文件的好方法,它遵循 XML 节点序列并且很容易理解:

  XElement element = XElement.Load(strFileName);

  var linqList = element.Elements("RoleSecurity")
                              .Where(entry => entry.Attribute("Name").Value == "A" && 
                               entry.Attribute("Workflowstatus").Value == "B")
                                  .Descendants("Accountgroup")
                                  .Where(x => x.Attribute("Name").Value == "Group1")
                                     .Descendants("Attribute")
                                     .SelectMany(id => id.Attribute("ID").Value);

【讨论】:

  • 感谢您的回答!我已经实施了公认答案的方法。我只是想知道哪种方法更适合我,为什么?
【解决方案3】:
XElement xcd = XElement.Load(strFileName);
IEnumerable<XElement> enumCust = from cust in xcd.Root.Elements("RoleSecurity")
           where cust.Attribute("Name").Value == strRole
           select cust;

现在应该可以了 你错过了.Root,这是在根节点下枚举所必需的
.Value 检索指定属性的字符串值

【讨论】:

  • 我正在尝试深入研究。就像我在问题中提到的那样,我正在尝试枚举并提取与特定角色名称、工作流状态和帐户组相对应的所有 ID。
【解决方案4】:

参考这篇文章:- http://www.dotnetcurry.com/ShowArticle.aspx?ID=564

foreach (XElement xcd xelement.Descendants("Id"))
    {
        Console.WriteLine((string)xcd);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多