LINQ to XML:使用包含XName和Value的XElement.Attributes()集合过滤查询

时间:2009-12-17 21:24:10

标签: xml linq linq-to-xml

使用LINQ to XML,XElements和XAttributes我想使用XElement的Attributes()IEnumerable XName / Value对集合上的精确匹配,针对提供的XName / Value对的IEnumerable Attributes集合过滤查询。

<container>
   <!-- logical group of settings -->
   <group name="group-one">
      <!-- setting with multiple key-value key options to return value -->
      <setting>
         <key app="a" command="go" />
         <key app="a" type="z" command="go" />
         <key app="a" type="z" flag="1" command="go" />
         <key app="a" type="z" target="OU812"/>
         <value>group-one item value A</value>
      </setting>
      <setting>
         <key app="a" />
         <key app="a" type="z" />
         <key app="a" type="z" flag="1" />
         <key app="c" type="z" command="go" />
         <value>group-one item value B</value>
      </setting>      
      ...
      ...
   </group>
   <group name="group-two">
      ...
      ...
   </group>
</container>

我怀疑使用Attributes()。SequenceEqual()与自定义IEqualityComparer来比较XAttribute.XName和XAttribute.Value是要走的路,但序列永远不会匹配,因为XElement(“key”)。Attributes()返回给定元素中所有元素的所有属性的集合。我已经尝试了类似于以下代码片段的任何数量的linq查询,包括嵌套查询和使用“let”语句,但我似乎无法做到正确。

var myAttributes = new List<XAttribute> {
                                        new XAttribute("app", "a"), 
                                        new XAttribute("type", "z")
                                        };

var xGroup = doc.Elements("group").First(g=>g.Attribute("name").Value==groupName);
var xSetting = (from s in xGroup.Elements("setting")
               // AttributesComparer() compares both the XAttribute.XName and XAttribute.Value properties to determine equality
               where s.Elements("key").Attributes().SequenceEqual(myAttributes, new AttributesComparer())
               select s).FirstOrDefault();

var xValue = xSetting.Element("value");

它应该返回一个代表<value>group-one item value B</value>

的XElement

现在,我已经决定使用XPathSelectElement() - 传递从提供的XAttributes()集合中的名称/值构建的XPath字符串。在这种情况下,生成的字符串将是:

group[@name='group-one']/setting[key[@app='n' and @type='z' and count(@*)=2]]/value

但是,我通常不会在集合中循环来在应用程序中构建字符串。我现在已经对此进行了一段时间的讨论,不幸的是,我很难理解如何使用现有方法使用紧凑的linq查询(或一系列查询)来实现更“优雅”的解决方案。

非常感谢任何反馈和/或建议!

1 个答案:

答案 0 :(得分:2)

您需要找到任何键匹配的设置,因此请使用Any扩展名方法。只需要进行一些小改动:

    var xSetting = (from s in xGroup.Elements("setting")
                    // AttributesComparer() compares both the XAttribute.XName and XAttribute.Value properties to determine equality
                    where s.Elements("key").Any(key => key.Attributes().SequenceEqual(myAttributes, new AttributesComparer()))
                    select s).FirstOrDefault();