C# 针对同级键值对的健壮LINQ到XML查询
第一个帖子,请温柔一点 我刚刚了解了LINQ to XML的所有优点和缺点,并试图破解它以实现我的目标: 给定这样的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<
<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();