2015-06-15 1 views
2

У меня есть узлы XML, как показано ниже.linq to 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 они находятся.

ответ

2

Предполагая, что вы хотите, чтобы счетчик «режим» отчетливых значения атрибутов в узлах с тот же идентификатор/имя, вам просто нужно проецировать из каждого элемента в группу в режим, затем взять четкую последовательность этих режимов, а затем подсчитать:

Вам просто нужно взять подсчет группы и также используйте SelectMany, чтобы «сгладить» ваши родительские узлы. (Или просто использовать 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 
+0

Спасибо за быстрый ответ @ Джон тарелочкам. Мне нужен отдельный счетчик во всех родительских узлах. Тот же узел/родительский узел не имеет значения. –

+0

@DevrajGadhavi: Не ясно, что вы подразумеваете под этим, и это не ясно в вашем вопросе. Измените свой вопрос, чтобы уточнить его. –

+1

@DevrajGadhavi: Я немного отредактировал свой ответ и поместил его в короткую, но полную программу, которая дает желаемые результаты. –