2013-12-09 2 views
1

У меня есть следующий XML:Group пунктом ограничения пунктов в группе

<R N="1"> 
    <MT N="Section" V="Section-1" /> 
    <MT N="Person" V="John" /> 
</R> 
<R N="2"> 
    <MT N="Section" V="Section-1" /> 
    <MT N="Person" V="Peter" /> 
</R> 
<R N="3"> 
    <MT N="Section" V="Section-2" /> 
    <MT N="Person" V="Joseph" /> 
</R> 
... ... 

<R N="N"> 
    <MT N="Section" V="Section-J" /> 
    <MT N="Person" V="PersonX" /> 
</R> 

И следующее GroupBy пункт, который формирует IEnumerable<IGrouping<string,XElement>>:

var something = MyElements.GroupBy 
(
    x => x.Elements("MT") 
    .First 
    (
     type => type.Attribute("N").Value == "Section" 
    ) 
    .Attribute("V").Value 
    , 
    x=>x 
); 

Я хотел бы иметь максимум 4 пунктов в каждой группе.

Я не могу использовать метод Take по выражению x=>x, так как его не IEnumerable<T>.

Вы знаете, как ограничить результаты для каждой группы?

+0

Можете ли вы описать, что данные, которые вы хотите, чтобы выбрать из XML? Похоже, ваш запрос не самый лучший, который вы можете использовать –

ответ

2

Вы можете использовать Take как это, если все, что вы хотите, это IEnumerable<IEnumerable<XElement>>:

var something = MyElements.GroupBy 
(
    x => x.Elements("MT") 
    .First 
    (
     type => type.Attribute("N").Value == "Section" 
    ) 
    .Attribute("V").Value 
    , 
    x => x, 
    (Key, Items) => Items.Take(4) 
); 

Если вам нужен ключ, а также вы можете сделать что-то вроде этого:

var something = MyElements.GroupBy 
(
    x => x.Elements("MT") 
    .First 
    (
     type => type.Attribute("N").Value == "Section" 
    ) 
    .Attribute("V").Value 
    , 
    x => x, 
    (Key, Items) => new { Key, Items = g.Take(4) } 
); 

Хотя, вы будете получите IEnumerable анонимного типа. Вам нужно будет перебирать коллекцию Items. Если вы не можете использовать анонимный тип (например, вам нужно, чтобы это было частью сигнатуры метода), вы всегда можете создать свой собственный тип результата или использовать Tuple.

+1

+1 для [GroupBy] (http://msdn.microsoft.com/en-us/library/bb534493 (v = vs.110) .aspx) перегрузка с результатом селектор (читаемость сомнительна, но это единственный вызов оператора) –

+0

Да, в моем приложении мне нужен ключ для рендеринга группы и всех элементов внутри. Анонимные элементы идеально подходят, спасибо большое. – Jose3d

1

Я считаю, что вы можете использовать следующие декларативного запроса, чтобы получить то, что вам нужно

var xdoc = XDocument.Load(path_to_xml); 
var query = from r in xdoc.Descendants("R") 
      let section = r.Elements("MT") 
          .First(mt => (string)mt.Attribute("N") == "Section") 
          .Attribute("V") 
      group r by (string)section into g 
      select g.Take(4); 
Смежные вопросы