LINQ to XML中的分组和求和

时间:2009-09-10 08:20:58

标签: linq-to-xml

鉴于下面的XML,我需要按InputItem进行分组,并总结所有年份的成本。所以结果应该是:

  1. 研究合约,7000
  2. 技术合同,5000
  3. Hospitality,2000
  4. 这是XML:

    <Inputs>
        <Inputs_Table_Row>
            <InputItem>Research Contracts</InputItem>
            <TotalYear1>1000</TotalYear1>
            <TotalYear2>2000</TotalYear2>
        </Inputs_Table_Row>
        <Inputs_Table_Row>
            <InputItem>Research Contracts</InputItem>
            <TotalYear1>2000</TotalYear1>
            <TotalYear2>2000</TotalYear2>
        </Inputs_Table_Row>
        <Inputs_Table_Row>
            <InputItem>Technical Contracts</InputItem>
            <TotalYear1>1000</TotalYear1>
            <TotalYear2>2000</TotalYear2>
        </Inputs_Table_Row>
        <Inputs_Table_Row>
            <InputItem>Technical Contracts</InputItem>
            <TotalYear1>1000</TotalYear1>
            <TotalYear2>1000</TotalYear2>
        </Inputs_Table_Row>
        <Inputs_Table_Row>
            <InputItem>Hospitality</InputItem>
            <TotalYear1>1000</TotalYear1>
            <TotalYear2>1000</TotalYear2>
        </Inputs_Table_Row>
    </Inputs>
    

    到目前为止,我的尝试仅仅是为了分组,但我没有成功:

    XDocument doc = XDocument.Load(@"c:\temp\CrpTotalsSimple.xml");
    
    var query = from c in doc.Descendants("Inputs_Table_Row")
                group new
                {
                    Item = (string)c.Element("InputItem")
                }
                by c.Element("InputItem")
                into groupedData
    
                select new
                {
                    ItemName = groupedData.Key.Value
                };
    
    foreach (var item in query)
        Console.WriteLine(String.Format("Item: {0}", item.ItemName));
    

    我该如何解决?

2 个答案:

答案 0 :(得分:2)

你需要像...这样的东西。

var query = from yearTotalEl in doc.Descendants()
            where yearTotalEl.Name.LocalName.StartsWith("TotalYear")
            group (decimal)yearTotalEl 
            by (string)yearTotalEl.Parent.Element("InputItem") into g
            select new {ItemName = g.Key, Sum = g.Sum()};

我正在使用decimal,因为我怀疑您正在处理可能包含小数部分的货币 - int否则会很好。

答案 1 :(得分:1)

看起来我只是缺少在group by子句中使用Value。这是我的工作解决方案:

var query = from c in doc.Descendants("Inputs_Table_Row")
group new
{
    Item = c.Element("InputItem").Value,
    ItemValue = (int)c.Element("TotalYear1") + (int)c.Element("TotalYear2")
 }
 by c.Element("InputItem").Value 
 into groupedData

 select new
 {
      ItemName = groupedData.Key,
      ItemTotal = groupedData.Sum(rec => rec.ItemValue)
  };