加入两个xml并计数

时间:2015-08-13 12:42:00

标签: c#

我是C#的新手。有谁知道如何分组两个xml并计算每个客户的订单数量?真的很困惑如何分组以及如何编写选择部分。

第一个xml

<Seq1>
  <Customer CustomerID="g">G</Customer>
  <Customer CustomerID="p">P</Customer>
</Seq1>

第二个xml

<Seq2>
  <Order OrderID="41" CID="p">card</Order>
</Seq2>

以及我想要的东西

<GroupJoin>
  <Join>
    <Customer CustomerID="g">G</Customer>
    <Group Count="0" />
  </Join>
  <Join>
    <Customer CustomerID="p">P</Customer>
    <Group Count="1">
      <Order OrderID="41" CID="p">card</Order>
    </Group>
  </Join>
</GroupJoin>

3 个答案:

答案 0 :(得分:0)

尝试类似:

Dictionary<string, List<string>> groups = [Seq2].GroupBy(cid => cid.Value);

Dictionary<string, List<string>> result = groups.Select(customerId = groups[customerId]);

答案 1 :(得分:0)

这是完整的解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input1 =
                "<Seq1>" +
                  "<Customer CustomerID=\"g\">G</Customer>" +
                  "<Customer CustomerID=\"p\">P</Customer>" +
                  "<Customer CustomerID=\"r\">R</Customer>" +
                  "<Customer CustomerID=\"s\">S</Customer>" +
                "</Seq1>";

            XElement element1 = XElement.Parse(input1);

            string input2 = 
                "<Seq2>" +
                  "<Order OrderID=\"11\" CID=\"r\">flash</Order>" +
                  "<Order OrderID=\"12\" CID=\"r\">mouse</Order>" +
                  "<Order OrderID=\"21\" CID=\"s\">phone</Order>" +
                  "<Order OrderID=\"22\" CID=\"s\">pc</Order>" +
                  "<Order OrderID=\"23\" CID=\"s\">camera</Order>" +
                  "<Order OrderID=\"41\" CID=\"p\">card</Order>" +
                "</Seq2>";

            XElement element2 = XElement.Parse(input2);


            var results =
                (from cust in element1.DescendantsAndSelf("Seq1").Elements("Customer")
                join order in element2.DescendantsAndSelf("Seq2").Elements("Order") on cust.Attribute("CustomerID").Value equals order.Attribute("CID").Value into comb
                from noMatch in comb.DefaultIfEmpty()
                select new { Customer = cust, Order = noMatch == null ? null : noMatch })
                .GroupBy(x => x.Customer.Attribute("CustomerID").Value, y => y)
                .ToList();
            //<GroupJoin>
            //  <Join>
            //    <Customer CustomerID="g">G</Customer>
            //    <Group Count="0" />
            //  </Join>
            //  <Join>
            //    <Customer CustomerID="p">P</Customer>
            //    <Group Count="1">
            //      <Order OrderID="41" CID="p">card</Order>
            //    </Group>
            //  </Join>
            //  <Join>
            //    <Customer CustomerID="r">R</Customer>
            //    <Group Count="2">
            //      <Order OrderID="11" CID="r">flash</Order>
            //      <Order OrderID="12" CID="r">mouse</Order>
            //    </Group>
            //  </Join>
            //  <Join>
            //    <Customer CustomerID="s">S</Customer>
            //    <Group Count="3">
            //      <Order OrderID="21" CID="s">phone</Order>
            //      <Order OrderID="22" CID="s">pc</Order>
            //      <Order OrderID="23" CID="s">camera</Order>
            //    </Group>
            //  </Join>
            //</GroupJoin>
            XElement groupJoin = new XElement("GroupJoin");
            foreach (var result in results)
            {
                XElement join = new XElement("Join");
                groupJoin.Add(join);
                join.Add(result.FirstOrDefault().Customer);
                XElement group = new XElement("Group");
                join.Add(group);
                if (result.FirstOrDefault().Order != null)
                {
                    var count = result.Count();
                    group.Add(new XAttribute("Count", count));
                    foreach (var order in result)
                    {
                        group.Add(order.Order);
                    }
                }
                else
                {
                    group.Add(new XAttribute("Count",0));
                }
            }


        }

    }
}
​

答案 2 :(得分:0)

您需要根据客户ID加入节点的后代,并将它们组合在一起以获得结果。以下查询应该是技巧:

var customers = XElement.Parse(@"<Seq1>
  <Customer CustomerID=""g"">G</Customer>
  <Customer CustomerID=""p"">P</Customer>
  <Customer CustomerID=""r"">R</Customer>
  <Customer CustomerID=""s"">S</Customer>
</Seq1>");

var orders = XElement.Parse(@"<Seq2>
  <Order OrderID=""11"" CID=""r"">flash</Order>
  <Order OrderID=""12"" CID=""r"">mouse</Order>
  <Order OrderID=""21"" CID=""s"">phone</Order>
  <Order OrderID=""22"" CID=""s"">pc</Order>
  <Order OrderID=""23"" CID=""s"">camera</Order>
  <Order OrderID=""41"" CID=""p"">card</Order>
</Seq2>");

var results = customers.Descendants("Customer").Join(orders.Descendants("Order"),
        c => c.Attribute("CustomerID").Value,
        o => o.Attribute("CID").Value,
        (c, o) => new{ Customer = c, Order = o})
    .GroupBy(x => x.Customer)
    .Select(g=>
    {
        var customerOrders = g.Select(x=>x.Order).ToArray();
        var customer = g.Key;
        var @group = customerOrders.Any()? new XElement    ("Group",customerOrders):new XElement("Group");
        @group.SetAttributeValue("Count", customerOrders.Length);
        return new XElement("Join",new[]{customer, @group});
    });
new XElement("GroupJoin", results).Dump();

以下是LinqPad中的输出:

Query results.