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

时间:2015-06-15 09:36:14

标签: c# .net linq xelement

我有如下的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

1 个答案:

答案 0 :(得分:2)

假设您想要计算不同的&#34;模式&#34;在具有相同ID /名称的节点内的属性值,您只需要从组中的每个元素投影到模式,然后采用这些模式的不同序列,然后对其进行计数:

您只需要计算该群组的数量,并使用SelectMany来&#34;展平&#34;你的父节点。 (或者只使用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