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

我该怎么做?

LINQ to XML select

基本上,你创建一个列表,其中包含第二个列表中的所有 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);