如何在LINQ to XML中对值进行分组/求和? [英] How can I group/sum values in LINQ to XML?

查看:42
本文介绍了如何在LINQ to XML中对值进行分组/求和?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图通过此方法来工作,但是在对数据进行分组时遇到了问题.我有一个XML结构

I've been trying to work thru this but I am having problems grouping the data. I have an XML structure

<FILE>
    <PLAN>
      <PLAN_ID>001</PLAN_ID>
      <PARTICIPANT>
        <PARTICIPANT_ID>9999</PARTICIPANT_ID>
        <INVESTMENTS>
          <INVESTMENT>
            <INVESTMENT_ID>ABC</INVESTMENT_ID>
            <BALANCE>1000</BALANCE>
            <ELECTION>0.00</ELECTION>
          </INVESTMENT>
          <INVESTMENT>
            <INVESTMENT_ID>XYZ</INVESTMENT_ID>
            <BALANCE>2000</BALANCE>
            <ELECTION>0.00</ELECTION>
          </INVESTMENT>
          <INVESTMENT>
            <INVESTMENT_ID>QWERTY</INVESTMENT_ID>
            <BALANCE>3000</BALANCE>
            <ELECTION>100.0</ELECTION>
          </INVESTMENT>
        </INVESTMENTS>
      </PARTICIPANT>
    </PLAN>
    <PLAN>
      <PLAN_ID>002</PLAN_ID>
      <PARTICIPANT>
        <PARTICIPANT_ID>9999</PARTICIPANT_ID>
        <INVESTMENTS>
          <INVESTMENT>
            <INVESTMENT_ID>ABC</INVESTMENT_ID>
            <BALANCE>2000</BALANCE>
            <ELECTION>0.00</ELECTION>
          </INVESTMENT>
          <INVESTMENT>
            <INVESTMENT_ID>XYZ</INVESTMENT_ID>
            <BALANCE>4000</BALANCE>
            <ELECTION>0.00</ELECTION>
          </INVESTMENT>
          <INVESTMENT>
            <INVESTMENT_ID>QWERTY</INVESTMENT_ID>
            <BALANCE>6000</BALANCE>
            <ELECTION>100.0</ELECTION>
          </INVESTMENT>
        </INVESTMENTS>
      </PARTICIPANT>
    </PLAN>
</FILE>

我从尝试获取所有BALANCE元素的总和开始

I started with just trying to get the SUM of all of the BALANCE elements

var doc = XDocument.Load("test.xml");

var sum = (from nd in doc.Descendants("BALANCE")
           select Int32.Parse(nd.Value)).Sum();

Console.WriteLine(sum);

那行得通,给了我18000.然后我想按PLAN_ID对数据进行分组,但是我不能得到除0以外的其他数据.

and that worked, giving me 18000. Then I wanted to group the data by the PLAN_ID but I cannot get it to give me other than 0.

var doc = XDocument.Load("test.xml");
var q = from x in doc.Descendants("PLAN")
        group x by x.Element("PLAN_ID").Value into gr
        select new
        {
             key = gr.Key,
             tot = (from tx in gr.Elements("BALANCE")
                    select (int)tx).Sum()
        };

我跑步时得到:

  • [0] {键="001",tot = 0}
  • [1] {键="002",tot = 0}

我哪里出错了?

推荐答案

问题是,当您要查找的元素比XML树更深时,您正在使用 Elements()一个级别.如果您在内部查询中切换到 Descendants(),那么您应该获得期望的结果.

The problem is that you're using Elements() when the element you're looking for is deeper into the XML tree than a single level. If you switch to Descendants() within your inner query, then you should get the results you're expecting.

var doc = XDocument.Load("test.xml");
var q = from x in doc.Descendants("PLAN")
        group x by x.Element("PLAN_ID").Value into gr
        select new
        {
             key = gr.Key,
             tot = (from tx in gr.Descendants("BALANCE")
                    select (int)tx).Sum()
        };

BALANCE节点比每个PLAN节点的内部节点深3个节点,因此应该可以解决问题.

The BALANCE nodes are 3 nodes deeper than the inner nodes of each PLAN node, so this should do the trick.

我个人而言,我喜欢使用lambda版本,因为它比较干净,所以为了完整起见,这里是使用lambda语法的关联解决方案:

Personally, I like using the lambda version because it's a bit cleaner, so just for completeness here's the associated solution using the lambda syntax:

var q = doc.Descedants("PLAN")
         .GroupBy(x => x.Element("PLAN_ID").Value))
         .Select(gr => new 
         {
             key = gr.Key,
             tot = gr.Sum(tx => (int)tx.Descendants("BALANCE"))
         });

这篇关于如何在LINQ to XML中对值进行分组/求和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆