I have got XML nodes as below.
...
<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>
....
What I need is
id name distinct-mode-count
--------------------------------------------
2343 some name 2
2344 some other name 1
I have tried below to get this.
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
}));
I am not sure how to get distinct_mode_count
in the above query.
Edit
I need distinct attribute value count for attribute "mode"
, regardless of which ParentNode
they are in.
Assuming you want the count of the distinct "mode" attribute values within the nodes with the same ID/name, you just need to project from each element in the group to the mode, then take the distinct sequence of those modes, then count it:
You just need to take the count of the group, and also use SelectMany
to "flatten" your parent nodes. (Or just use myXml.Descendants("Node")
to start with.)
Short but complete example which gives your desired results:
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);
}
}
}
Alternatively:
XElement myXML = XElement.Load("test.xml");
var nodeAttributes = myXML
.Descendants("Node")
.GroupBy(...)
// Remaining code as before
See more on this question at Stackoverflow