2011-04-09 20 views
5

Quiero utilizar LINQ para convertir XML de entrada en XML de salida al realizar GROUPBY en el campo "Resumen" y SUMAR el campo Balance.LINQ to XML GroupBy

de entrada XML: 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> 

Salida:

<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> 

He intentado esto pero no es capaz de conseguir nodos/elementos:

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"))))); 

cualquier ayuda ser apreciado. Gracias por adelantado.

Respuesta

3

Yo sugeriría que se proyecta en objetos normales, agrupándolos, a continuación, se proyecta de nuevo en 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

En caso de que no desea que los objetos de intermediación puede utilizar

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"); 

o con el método sintaxis podría utilizar

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 = new groupData XElement ("raíz", de grp en newList grupo grp por grp.ContractPeriod en g seleccione nuevo XElement ("Período", nuevo XElement ("Key", G.KEY), nuevo XElement ("FullName", g.Firs(). Nombre completo)));

+0

podría formatear su código resaltando y presionando Ctrl + k – WhatsThePoint