xml - LINQ to XML : filter a query using XElement. 具有 XName 和 Value 的 Attributes() 集合

标签 xml linq linq-to-xml

使用 LINQ to XML、XElements 和 XAttributes 我想使用 XElement 的 Attributes() IEnumerable XName/Value 对集合与提供的 IEnumerable Attributes XName/Value 对集合的完全匹配来过滤查询。

<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>

我怀疑使用带有自定义 IEqualityComparer 的 Attributes().SequenceEqual() 来比较 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 查询(或一系列查询)来实现更“优雅”的解决方案感到困惑。

如有任何反馈和/或建议,我们将不胜感激!

最佳答案

您需要找到 any 键匹配的设置,因此请使用 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();

关于xml - LINQ to XML : filter a query using XElement. 具有 XName 和 Value 的 Attributes() 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1924693/

相关文章:

c# - 如何根据自定义顺序订购列表项?

Android - 如何仅向背景图像添加动画(放大)而不影响其他图像?

c# - 如何使用 LINQ-to-Entity 按包含的对象进行查询

c# - 为什么要编写自定义 LINQ 提供程序?

silverlight - 不能在 Silverlight 中使用 XDocument?

c# - Linq To XML、yield 等

java - 从 XML 或 JSON 反序列化不受信任的数据

html - 如何快速关闭 Vim 中的 HTML 标签?

java - 使用java解析xml中的元素数组

c# - 如何使用层次结构级别填充 TreeViewControl?