C# linq 从 XElement 树中选择重复项

Posted

技术标签:

【中文标题】C# linq 从 XElement 树中选择重复项【英文标题】:C# linq select duplicate from an XElement tree 【发布时间】:2021-10-15 17:24:51 【问题描述】:

这是我的 XElement 树

        XElement myShoppingList = new XElement("myShoppingList",
            new XElement("Pasadena", new XAttribute("Vendor", "Tesla"),
                new XElement("Car",
                    new XElement("model3",
                        new XElement("Black")))),
            new XElement("LasVegas", new XAttribute("Vendor", "Tesla"),
                new XElement("Car",
                    new XElement("modelY",
                        new XElement("White")))),
            new XElement("Pasadena", new XAttribute("Vendor", "Apple"),
                new XElement("Phone",
                    new XElement("model13",
                        new XElement("Black")))),
            new XElement("Pasadena", new XAttribute("Vendor", "Apple"),
                new XElement("Phone",
                    new XElement("model12",
                        new XElement("White")))));

我似乎无法让这个工作,第一个问题 - 搜索“帕萨迪纳”时,我应该得到 3 次重复:

        var query = myShoppingList.Elements().AsEnumerable()
           .GroupBy(x => x.XPathSelectElement("Pasadena"))
          .Where(g => g.Count() > 1)
          .Select(y => new  Element = y.Key, Counter = y.Count() )
          .ToList();

在 LasVegas 搜索 Tesla 时,我预计会有 1 次重复

        var query = myShoppingList.Elements().AsEnumerable()
           .GroupBy(x => x.XPathSelectElement("Pasadena[@Name='Tesla']"))
          .Where(g => g.Count() > 1)
          .Select(y => new  Element = y.Key, Counter = y.Count() )
          .ToList();

最后我想搜索“白色”,无论是谁制作了小部件,然后显示它的制造商。所以我期待 2 次重复:

       var query = myShoppingList.Elements().AsEnumerable()
           .GroupBy(x => x.XPathSelectElement("../../../White"))
          .Where(g => g.Count() > 1)
          .SelectMany(y => y)
          .ToList();

我无法让这个工作我做错了什么?

【问题讨论】:

不工作是什么意思? 我不断得到这个回报:System.Collections.Generic.List1[<>f__AnonymousType02[System.Xml.Linq.XElement,System.Int32]] 在这种情况下,您的 GroupBy 看起来没有必要。你可以简单地做.Select(e => e.Name.LocalName);。也不需要计数。 是的,在我已经知道要提前选择哪个元素的情况下,我完全了解 select 语句。但是,我的实际 XML 列表有我试图识别的随机重复项。而且因为它们是随机的,我不知道会发生什么。因此我无法进行高级选择。 @Syntax_MM 我认为您必须在此处详细说明您的期望。 .GroupBy(x => x.XPathSelectElement("Pasadena")) 您的意图尚不清楚。每个“Pasadena”元素都是一个单独的对象,因此 element1 != element2 不会被分组。你的意思是myShoppingList.XPathSelectElements("/Pasadena") 【参考方案1】:

我似乎无法让这个工作,第一个问题 - 搜索时 “帕萨迪纳”我应该得到 3 次重复:

这是您想要实现的目标吗? :

var query = myShoppingList.XPathSelectElements("Pasadena")
    .GroupBy(x => x.Name)
    .Select(y => new  Element = y.Key, Counter = y.Count() );

在 LasVegas 搜索 Tesla 时,我预计会有 1 次重复

你可以这样试试。

var query = myShoppingList.XPathSelectElements("Pasadena")
    .Where(x => x.Attributes().Any(x => x.Name == "Vendor" && x.Value == "Tesla"))
    .GroupBy(x => x.Name)
    .Select(y => new  Element = y.Key, Counter = y.Count() );

对于这个,我不确定这是否是您想要实现的目标

var query = myShoppingList.XPathSelectElements("//White")
    .GroupBy(x => x.Name)
    .Select(y => new  Element = y.Key, Counter = y.Count() );

【讨论】:

谢谢,就是这样!对于第二个建议,如果我在“White”之后有更多 XML 节点怎么办,要键入什么其他字符来代替“//”? 很高兴我能帮上忙。如果您需要“//white”的特定子级,则可以执行“//white/MyChild”。此时,您可以使用 XPathSelectElements 或 linq 从这里做很多事情。

以上是关于C# linq 从 XElement 树中选择重复项的主要内容,如果未能解决你的问题,请参考以下文章

从 XElement 获取子元素 [重复]

使用linq c#从数据表中选择整个重复行

C#:如何从 XElement 中获取名称(带前缀)作为字符串?

使用 LINQ 和 XElement 查询 SQL 表

使用 LINQ XML 绑定 ComboBox

Linq-to-XML XElement.Remove() 留下不需要的空白