根据字典过滤XElements列表

时间:2013-06-05 10:30:37

标签: c# linq

这是我的xml文件:

<items>
  <item code="1">
    <info1>LOREM</info1>
    <info2>IPSUM</info2>
    <info3>DOLOR</info3>
  </item>
  <item code="2">
    <info1>LOREM</info1>
    <info2>AMET</info2>
    <info3>CONSECTETUER</info3>
  </item>
  <item code="3">
    <info1>LOREM</info1>
    <info2>IPSUM</info2>
    <info3>CONSECTETUER</info3>
  </item>
</items>

我想根据存储在该字典上的标准提取一些项目代码:

{ "info1", "LOREM" }
{ "info2", "IPSUM" }

我写了那个linq查询:

var test =  from element in xml.Descendants("item").Elements()
        from param in dicoParams
        where param.Key == element.Name.ToString() && param.Value == element.Value
        select element.Parent.Attribute("code");

但输出是:

code="1"
code="1"
code="2"
code="3"
code="3"

和我的期望是:

code="1"
code="3"

我们可以注意到查询返回的元素满足至少一个条件,但我希望它满足这两个条件。

我怎么能写这个查询?

3 个答案:

答案 0 :(得分:3)

我认为您还期望2,因为2包含info1,其中包含LOREM

无论如何,我认为这就是你要找的东西:

var test =  from element in xml.Descendants("item")
    from param in dicoParams
    where element.Elements()
        .Any(e => e.Name.ToString() == param.Key && e.Value == param.Value)
    select element.Attribute("code");

无论匹配数量如何,这都只输出一个代码。

实际上,正如@ user1068352在评论中提到的那样,您似乎想要与字典中的所有项目匹配的项目

如果是这种情况,请尝试:

var test = from element in xml.Descendants("item")
    where dicoParams.All(d => element.Elements
        .Any(e => e.Name.ToString() == d.Key && e.Value == d.Value))
    select element.Attribute("code");

答案 1 :(得分:0)

这样的事情应该有效:

var test =
    from element in xml.Descendants("item")
    where element.Elements()
        .Any(x =>
            dicoParams.ContainsKey(x.Name.ToString())
            && dicoParams[x.Name.ToString()] == x.Value)
    select element.Attribute("code");

但正如其他人指出元素“2”与您提供的数据匹配。

答案 2 :(得分:0)

 var test1 = (from element in elem.Descendants().Elements()
                         from item in val
                         where item.Key == element.Name.ToString() && item.Value == element.Value
                         select element.Parent.Attribute("code")).GroupBy(t => t.Parent.Attribute("code"));

你也可以使用group by