LINQ to XML select
本文关键字:select XML to LINQ | 更新日期: 2023-09-27 18:36:54
我有两个xml文档,其中包含一些元素,例如
文档1
<Item id="22"/>
<Item id="33"/>
<Item id="44"/>
...
文档2
<Item id="33"/>
<Item id="44"/>
<Item id="66"/>
<Item id="88"/>
...
我需要一个查询来选择仅 doc1 中缺少的那些元素在 doc2 中忽略其他 doc2 元素。
在这种情况下,结果将是:
<Item id="22"/>
我该怎么做?
基本上,你创建一个列表,其中包含第二个列表中的所有 id,并检查 doc1 的每个项目是否在列表中。性能方面,我认为这不是最佳选择 - 但它应该有效
var qry = from item in doc1.Descendants("Item")
where
!(from item2 in doc2.Descendants("Item")
select item2.Attribute("id"),Value
).ToList().Contains(item.Attribute("id").Value)
select item;
在上面的linq语句中,我认为ids列表是为doc1中的每个元素创建的。更好的选择是先创建列表,然后在下一条语句中使用该列表:
List<string> items = (from item2 in doc2.Descendants("Item")
select item2.Attribute("id").Value
).ToList();
var qry = from item in doc1.Descendants("Item")
where !items.Contains(item.Attribute("id").Value)
select item;
可能是类似
doc1.Where(i1=>doc2.All(i2 => i2.id != i1.id))
可以带你去那里。
但是,这是在 doc2 上对 doc1 中的每个元素执行子查询。确保它们很小!
最简单的方法是使用 MoreLinq 库中的 ExceptedBy
方法。假设Item
元素直接位于根元素下方:
var doc1 = XDocument.Load("doc1.xml");
var doc2 = XDocument.Load("doc2.xml");
var doc1Elements = doc1.Root.Elements("Item");
var doc2Elements = doc2.Root.Elements("Item");
var diff = doc1Elements.ExceptBy(doc2Elements, e => e.Attribute("id").Value);