XML结构:
<Root>
<Place name="Place 1">
<Event type="Type 1">
<Title>Lorem ipsum dolor sit amet</Title>
<Description>Lorem ipsum</Description>
<People>73</People>
</Event>
<Event type="Type 2">
<Title>Lorem ipsum dolor sit amet</Title>
<Description>Lorem ipsum</Description>
<People>3</People>
</Event>
</Place>
<Place name="Place 2">
<Event type="Type 1">
<Title>Lorem ipsum dolor sit amet</Title>
<Description>Lorem ipsum</Description>
<People>10</People>
</Event>
<Event type="Type 2">
<Title>Lorem ipsum dolor sit amet</Title>
<Description>Lorem ipsum</Description>
<People>49</People>
</Event>
</Place>
</Root>
我需要在所有地方对事件类型进行分组,并获得每种事件类型的总人数。我能想到的就是:
var event_types = from event in data.Elements("Event").Attributes("type")
group event by event.Value into g
select g;
但这只是分组,我完全不知道如何在尝试几个小时后获得总和。
结果应如下所示:
+------------+--------+
| Type | People |
+------------+--------+
| Type 1 | 83 |
| Type 2 | 52 |
+------------+--------+
答案 0 :(得分:3)
你可以试试这个:
var events=document.Descendants("Event")
.GroupBy(e=>(string)e.Attribute("type"))
.Select(g=>new {Type=g.Key, People=g.Sum(e=>(int)e.Element("People"))})
答案 1 :(得分:2)
以下是我将如何做到这一点:
var events = data.Root.Elements("Place")
.SelectMany(p => p.Elements("Event"))
.GroupBy(e => (string)e.Attribute("type"))
.Select(g => new {
Type = g.Key,
People = g.Sum(e => Convert.ToInt32(e.Element("People").Value))
});
将其分解,我们首先找到所有Event
个节点:
.SelectMany(p => p.Elements("Event"))
// returns an IEnumerable<XElement> of your four Events
然后我们按属性值进行分组:
.GroupBy(e => (string)e.Attribute("type"))
// returns an IEnumerable<IGrouping<string, XElement>> of two groups
最后,我们通过选择一个新的匿名类型来创建结果,其中Type
属性是组键,People
属性是子People
元素中值的总和(首先转换为int
):
.Select(g => new {
Type = g.Key, // "Type 1" or "Type 2"
People = g.Sum(e => Convert.ToInt32(e.Element("People").Value))
});
// g is the IGrouping<string, XElement>. You can use the LINQ method
// Sum across each XElement (e), e being your Event.
输出正如您所料:
+------------+--------+
| Type | People |
+------------+--------+
| Type 1 | 83 |
| Type 2 | 52 |
+------------+--------+
编辑:如另一个答案所示,.GroupBy
之前的行可以替换为data.Descendants("Event")
- 我忽略了这条捷径。