linq to XML:每组的唯一属性值计数

linq to XML: unique attribute value count per group

我有 XML 个节点如下。

...
<ParentNode>
    <Node id="2343" name="some name" mode="Some Mode">
         //Some child nodes here
    </Node>
    <Node id="2344" name="some other name" mode="Some Mode">
         //Some child nodes here
    </Node>
    ...
</ParentNode>
<ParentNode>
    <Node id="2343" name="some name" mode="Some Other Mode">
         //Some child nodes here
    </Node>
    <Node id="2344" name="some other name" mode="Some Mode">
         //Some child nodes here
    </Node>
</ParentNode>
....

我需要的是

id      name             distinct-mode-count
--------------------------------------------
2343    some name        2
2344    some other name  1

我已经在下面尝试得到这个。

XElement myXML = XElement.Load(filePath);

IEnumberable<XElement> parentNodes = myXML.Descendants("ParentNode");

var nodeAttributes = parentNodes.Select(le => le.Descendants("Node")
    .GroupBy(x => new { 
                          id = x.Attribute("id").Value, 
                          name = x.Attribute("name").Value 
                      }).Select(g => new { 
                          id = g.Key.id, 
                          name = g.Key.name, 
                          distinct_mode_count = // This is where I am stuck
                      }));

我不确定如何在上面的查询中得到 distinct_mode_count

编辑

我需要属性 "mode" 的不同属性值计数,无论它们在哪个 ParentNode 中。

假设你想要统计ID/name节点内不同的"mode"属性值,你只需要从组中的每个元素投影到模式,然后取这些模式的不同顺序,然后计算它:

你只需要计算组的数量,同时使用SelectMany到"flatten"你的父节点。 (或者只使用 myXml.Descendants("Node") 作为开头。)

给出您想要的结果的简短但完整的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XElement myXML = XElement.Load("test.xml");

        IEnumerable<XElement> parentNodes = myXML.Descendants("ParentNode");
        var nodeAttributes = parentNodes
            .SelectMany(le => le.Descendants("Node"))
            .GroupBy(x => new { 
                Id = x.Attribute("id").Value, 
                Name = x.Attribute("name").Value 
            })
            .Select(g => new {
                g.Key.Id,
                g.Key.Name,
                DistinctModeCount = g.Select(x => x.Attribute("mode").Value)
                                     .Distinct()
                                     .Count()
            });
        foreach (var item in nodeAttributes)
        {
            Console.WriteLine(item);
        }
    }
}

或者:

XElement myXML = XElement.Load("test.xml");

var nodeAttributes = myXML
    .Descendants("Node")
    .GroupBy(...)
    // Remaining code as before