C# 针对同级键值对的健壮LINQ到XML查询

C# 针对同级键值对的健壮LINQ到XML查询,c#,linq-to-xml,robustness,C#,Linq To Xml,Robustness,第一个帖子,请温柔一点 我刚刚了解了LINQ to XML的所有优点和缺点,并试图破解它以实现我的目标: 给定这样的XML文件- <list> <!-- random data, keys, values, etc.--> <key>FIRST_WANTED_KEY</key> <value>FIRST_WANTED_VALUE</value> <key>SECOND_WANTED_KEY<

第一个帖子,请温柔一点

我刚刚了解了LINQ to XML的所有优点和缺点,并试图破解它以实现我的目标:

给定这样的XML文件-

<list>
<!-- random data, keys, values, etc.-->

  <key>FIRST_WANTED_KEY</key>
  <value>FIRST_WANTED_VALUE</value>

  <key>SECOND_WANTED_KEY</key>
  <value>SECOND_WANTED_VALUE</value> <!-- wanted because it's first -->

  <key>SECOND_WANTED_KEY</key>
  <value>UNWANTED_VALUE</value>  <!-- not wanted because it's second -->

  <!-- nonexistent <key>THIRD_WANTED_KEY</key> -->
  <!-- nonexistent <value>THIRD_WANTED_VALUE</value> -->

<!-- more stuff-->
</list>
我的问题是那应该是什么。。。是我试过,比如说,丑陋,我知道

second_wanted_value = ((XElement)y.ElementsAfterSelf()
                      .Where(w => w.Value=="SECOND_WANTED_KEY")
                      .FirstOrDefault().NextNode).Value
这应该允许密钥在任何地方,或者不存在,但这还没有解决,因为空XElement上的.NextNode似乎不起作用

我还尝试添加了一个

.Select(t => { 
    if (t==null) 
        return new XElement("SECOND_WANTED_KEY",""); 
    else return t;
})
在where之后加入子句,但这也不起作用

我愿意接受建议、建设性的批评、链接、参考资料或对谷歌的短语建议等。我在谷歌搜索和检查S.O.方面做了相当多的工作,因此任何帮助都将不胜感激

谢谢

编辑: 让我给这个增加一层复杂性——我应该首先包括这个。假设XML文档如下所示:

<lists>
    <list>
      <!-- as above -->
    </list>
    <list>
      <!-- as above -->
    </list>
</lists>
这将获取所有的键值对,但我不确定它是否能保证将这些对正确地关联到它们的父`'元素。这两种方法之间的任何想法或比较都会有所帮助

状态更新4/9/10

到目前为止,我仍然认为哈希集方法是最受欢迎的。似乎.NET完成的大部分XML处理都是按文档顺序完成的——到目前为止,我所有的测试用例都已经完成了


我会提供悬赏和/或追加投票的答案,但没有足够的代表分数。我今天会决定一个答案,所以让他们进来!谢谢。

这将获取包含第二个\u关键字的第一个元素之后的第一个元素的值:

根据需要添加空检查

XDocument doc = ...

var wantedKeyValuePairs =
    from keyElement in doc.Root.Elements("key")
    let valueElement = keyElement.ElementsAfterSelf("value").First()
    select new { Key = keyElement.Value, Value = valueElement.Value } into kvp
    group kvp by kvp.Key into g
    select g.First();

说明:此查询获取每个元素及其后续元素,并与这些元素形成键值对。然后,它按键对键值对进行分组,并只为每个键取第一个键值对

谢谢-这是否支持筛选,因为可能有一些我不想要的键值对?例如,如果出现不需要的\u KEY不需要的\u值,这会不会无法拾取它?您只需要在第一个select:where kvp.KEY!=不需要的_key感谢您的回复-很有意义-我可以为每个key添加多个这样的语句。对我上面的补充/澄清有什么想法吗?我认为这与我想要的最接近,不过如果有任何人提出更多建议,我会洗耳恭听。谢谢
HashSet<string> wantedKeys = new HashSet<string>();
wantedKeys.Add("FIRST_WANTED_KEY");
//...add more keys here
var kvp = from a in x.Descendants().Where(a => wantedKeys.Contains(a.Value))
          select new KeyValuePair<string,string>(a.value,
             ((XElement)a.NextNode).Value);
XDocument doc;

string result = (string)doc.Root
                           .Elements("key")
                           .First(node => (string)node == "SECOND_WANTED_KEY")
                           .ElementsAfterSelf("value")
                           .First();
XDocument doc = ...

var wantedKeyValuePairs =
    from keyElement in doc.Root.Elements("key")
    let valueElement = keyElement.ElementsAfterSelf("value").First()
    select new { Key = keyElement.Value, Value = valueElement.Value } into kvp
    group kvp by kvp.Key into g
    select g.First();