【问题标题】:Using LINQ to aggregate multiple nested elements in XDocument使用 LINQ 聚合 XDocument 中的多个嵌套元素
【发布时间】:2016-05-12 21:15:12
【问题描述】:

我有以下 XML(解析为 XDocument):

XDocument nvdXML = XDocument.Parse(@"<entry id='CVE-2016-1926'>
<vulnerable-configuration id='http://www.nist.gov/'>
  <logical-test operator='OR' negate='false'>
    <fact-ref name='A'/>
    <fact-ref name='B'/>
    <fact-ref name='C'/>
  </logical-test>
</vulnerable-configuration>
<vulnerable-configuration id='http://www.nist.gov/'>
  <logical-test operator='OR' negate='false'>
    <fact-ref name='X'/>
    <fact-ref name='Y'/>
    <fact-ref name='Z'/>
  </logical-test>
</vulnerable-configuration></entry>");

我想为每个条目获取每个“名称”属性的单个集合/列表(在这种情况下,只有一个条目,其名称列表将由 ['A','B','C', 'X','Y','Z'])

这是我的代码:

var entries = from entryNodes in nvdXML.Descendants("entry")
                          select new CVE
                          {
                              //VulnerableConfigurations = (from vulnCfgs in entryNodes.Descendants(vulnNS + "vulnerable-configuration").Descendants(cpeNS + "logical-test")
                              //                            select new VulnerableConfiguration
                              //                            {
                              //                                Name = vulnCfgs.Element(cpeNS + "fact-ref").Attribute("name").Value
                              //                            }).ToList()
                              VulnerableConfigurations = (from vulnCfgs in entryNodes.Descendants("vulnerable-configuration")
                                                          from logicalTest in vulnCfgs.Descendants("logical-test")
                                                          select new VulnerableConfiguration
                                                          {
                                                              Name = logicalTest.Element("fact-ref").Attribute("name").Value
                                                          }).ToList()
                          };

不幸的是,这个(评论和未评论的)查询只会导致 VulnerableConfigurations ['A','X'],而不是 ['A','B','C ','X','Y','Z']

如何修改我的查询,以便选择每个列表的每个元素(假设可能有 1+ 个嵌套列表)?

注意,我确实搜索过 dup 的,虽然也有类似的问题,但大部分都很具体,要求分组/求和/操作,或者与 XML 解析无关。


最终的工作代码(感谢接受的答案):

var entries = from entryNodes in nvdXML.Descendants("entry")
                          select new CVE
                          {
                              VulnerableConfigurations = (from vulnCfgs in entryNodes.Descendants("fact-ref")
                                                          select new VulnerableConfiguration
                                                          {
                                                              Name = vulnCfgs.Attribute("name").Value
                                                          }).ToList()
                          };

【问题讨论】:

    标签: c# linq xml-parsing linq-to-xml


    【解决方案1】:

    如果你只有一个条目,你可以试试这个:

    var entries =(from fact in nvdXML.Descendants("fact-ref")
                  select new VulnerableConfiguration
                             {
                               Name = fact.Attribute("name").Value
                             }).ToList();
    

    Descendants 方法将按文档顺序返回与该名称匹配的所有后代元素。

    如果您有多个条目,并且想要为每个条目返回一个列表,您可以执行以下操作:

    var entries =(from entry in nvdXML.Descendants("entry")
                  select  entry.Descendants("fact-ref").Select(f=>f.Attribute("name").Value).ToList()
                 ).ToList();
    

    在这种情况下,您将获得一个列表列表 (List&lt;List&lt;string&gt;&gt;)

    更新

    您的问题是因为您在 logical-test 元素上奉承您的查询,而在您的 xml 中您有两个。现在在您的select 中,您使用的是Element 方法,它只给您一个元素,这样您就有了AX,它们是logical-test 元素中的第一个fact-ref 元素

    【讨论】:

    • 我没有意识到你不需要遍历树来获取嵌套元素。你能解释一下为什么我的原始查询只得到 ['A', 'X']?
    • 我更新了我的问题以包含我的最终代码,它包含了我正在使用的父对象(CVE,它包含一个 VulnerableConfigurations 列表)。你的回答让我到了那里,所以 +1 并为你打勾,先生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多