LINQ to XML GroupBy - PullRequest
       23

LINQ to XML GroupBy

5 голосов
/ 09 апреля 2011

Я хочу использовать LINQ для преобразования входного XML в выходной XML, выполнив GROUPBY в поле «Сводка» и SUM до поля Баланс.

Входной 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 ]

8 голосов
/ 09 апреля 2011

Если вам не нужны промежуточные объекты, вы можете использовать

    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");
3 голосов
/ 09 апреля 2011

Я бы предложил проецировать в обычные объекты, группировать их, а затем проецировать обратно в 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"))
         )
     );
0 голосов
/ 10 июля 2017

var groupData = new XElement ("Root", из grp в newList Группа GRP по grp.ContractPeriod в г выберите новый XElement («Период», новый XElement («Ключ», г.Кей), новый XElement ("FullName", г.Firs (). FullName)));

...