2011-04-09 192 views
5

我想要使用LINQ将输入XML转换为输出XML,方法是在“摘要”字段上执行GROUPBY,然后求出余额字段。LINQ to XML GroupBy

输入XML:

<Root> 
    <Account> 
    <Summary>Checking</Summary> 
    <Comprehensive>Interest Checking Account</Comprehensive> 
    <Currency>Dollar</Currency> 
    <Balance>10000000.000000</Balance> 
    </Account> 
    <Account> 
    <Summary>Savings</Summary> 
    <Comprehensive>Market Account</Comprehensive> 
    <Currency>Dollar</Currency> 
    <Balance>20000000.000000</Balance> 
    </Account> 
    <Account> 
    <Summary>Checking</Summary> 
    <Comprehensive>Interest Checking Account</Comprehensive> 
    <Currency>Dollar</Currency> 
    <Balance>50000000.000000</Balance> 
    </Account> 
</Root> 

输出XML:

<Root> 
    <Account> 
    <Summary>Checking</Summary> 
    <Comprehensive>Interest Checking Account</Comprehensive> 
    <Currency>Dollar</Currency> 
    <Balance>60000000.000000</Balance> 
    </Account> 
    <Account> 
    <Summary>Savings</Summary> 
    <Comprehensive>Market Account</Comprehensive> 
    <Currency>Dollar</Currency> 
    <Balance>20000000.000000</Balance> 
    </Account> 
</Root> 

我试过,但没能获得节点/元素:

XElement groupData = new XElement("Root", 
    chartData.Elements().GroupBy(x => x.Element("Summary").Value). 
     Select(g => new XElement("Account", g.Key, g.Elements("Comprehensive"), 
      g.Elements("Currency"), 
      g.Sum(
       s => 
       (decimal) 
       s.Element("Balance"))))); 

任何帮助将不胜感激。提前致谢。

回答

3

我建议伸入正常的对象,将它们分组,然后投射回XML:

var data = from acct in chartData.Elements() 
      select new { 
       Summary = (string)acct.Element("Summary"), 
       Comprehensive = (string)acct.Element("Comprehensive"), 
       Currency = (string)acct.Element("Currency"), 
       Balance = (decimal)acct.Element("Balance"), 
      }; 

var grouped = from acct in data 
       group acct by acct.Summary into g 
       select new { 
        Summary = g.Key, 
        Comprehensive = g.First().Comprehensive, 
        Currency = g.First().Comprehensive, 
        Balance = g.Sum(), 
       }; 

var groupData = new XElement("Root", 
    from g in grouped 
    select new XElement("Account", 
      new XElement("Summary", g.Summary), 
      new XElement("Comprehensive", g.Comprehensive), 
      new XElement("Currency", g.Currency), 
      new XElement("Balance", g.Balance.ToString("0.000000")) 
     ) 
    ); 
8

如果你不想中介的对象,你可以使用

XDocument input = XDocument.Load("input.xml"); 
    XDocument output = 
     new XDocument(
      new XElement(input.Root.Name, 
       from account in input.Root.Elements("Account") 
       group account by account.Element("Summary").Value into g 
       select new XElement("Account", 
        g.ElementAt(0).Elements().Where(e => e.Name != "Balance"), 
        new XElement("Balance", g.Elements("Balance").Sum(b => (decimal)b) 
        )))); 
    output.Save("output.xml"); 

或方法您可以使用的语法

XDocument input = XDocument.Load(@"input.xml"); 
    XDocument output = new XDocument(
      new XElement(input.Root.Name, 
       input.Root.Elements("Account") 
       .GroupBy(a => a.Element("Summary").Value) 
       .Select(g => new XElement("Account", 
        g.ElementAt(0).Elements().Where(e => e.Name != "Balance"), 
        new XElement("Balance", g.Elements("Balance").Sum(b => (decimal)b) 
        ))))); 
    output.Save("output.xml"); 
0

var groupData = new XElement(“Root”, from grp in newList group grp by grp.ContractPeriod into g 选择新的XElement(“Period”, new XElement(“Key”,g.Key), new XElement(“FullName”,g.Firs()。全名)));

+0

请问您可以通过突出显示并按下Ctrl + k来格式化您的代码 – WhatsThePoint 2017-07-10 13:26:29