Группировка по имени всех потомков - очень простое решение: (x
- это имя вашего XDocument)
foreach (var e in x.Descendants("chkr"))
{
foreach (var v in e.Descendants()
.Where(ee => ee.Name != "ab" && ee.Name != "tt")
.GroupBy(ee => ee.Name)
.Select(ee => new { Name = ee.Key, Count = ee.Count() }))
{
if (v.Count > 1)
Console.WriteLine($"<chkr id={e.Attribute("id").Value}> contains the tag <{v.Name}> {v.Count} times.");
}
}
С вашим XML этот код будет выводить
<chkr id=3>
содержит тег <foo>
2 раза.
РЕДАКТИРОВАТЬ: Если вы хотите, чтобы результаты, как указано в вашем комментарии, просто измените свой код на следующее:
List<string> names = new List<string>();
List<int> counts = new List<int>();
foreach (var e in x.Descendants("chkr"))
{
names = new List<string>();
counts = new List<int>();
foreach (var v in e.Descendants().Where(ee => ee.Name != "ab" && ee.Name != "tt").GroupBy(ee => ee.Name).Select(ee => new { Name = ee.Key, Count = ee.Count() }))
{
if (v.Count > 1)
{
names.Add(v.Name.ToString());
counts.Add(v.Count);
}
}
if (names.Any())
Console.WriteLine($"<chkr id={e.Attribute("id").Value}> contains the tag/tags {String.Join(",", names)} {String.Join(",", counts)} times.");
}