2011-04-09 190 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