使用名称标记比较XML节点值并删除标记

本文关键字:节点 删除 XML 比较 | 更新日期: 2023-09-27 18:02:26

我有XML示例

<order>
 <orderItem>
    <OrderId>Ex1</OrderId>
    <amount>100</amount>
 </orderItem>
 <orderItem>
    <OrderId>Ex2</OrderId>
    <amount>150</amount>
 </orderItem>
 <orderItem>
    <OrderId>Ex1</OrderId>
    <amount>250</amount>
 </orderItem>
</order>

如果OrderId标签值等于另一个OrderId标签值,则添加Amount标签并删除新添加的标签。

我需要的结果输出应该如下所示

<order>
 <orderItem>
  <OrderId>Ex1</OrderId>
  <amount>350</amount>
 </orderItem>
 <orderItem>
  <OrderId>Ex2</OrderId>
  <amount>150</amount>
 </orderItem>
</order>

OrderId值应该是change。

string filename = "File Location";
var doc = XDocument.Load(filename);
var results = doc.Descendants("order");
var orderItemcount = results.Descendants("orderItem").Count(); 

我不知道下一步该做什么。

Thanks in Advance.

:

My New XML Like Below

<order>
 <orderItem>
   <Orders>
     <OrderId>Ex1</OrderId>
     <amount>100</amount>
   </Orders>
 </orderItem>
 <orderItem>
  <Orders>
   <OrderId>Ex2</OrderId>
   <amount>150</amount>
  </Orders>
 </orderItem>
 <orderItem>
  <Orders>
    <OrderId>Ex1</OrderId>
    <amount>250</amount>
  </Orders>
</orderItem>
</order>

如果OrderId是相同的,那么将OrderItem标签添加到匹配标签。结果i需要像

下面
<order>
 <orderItem>
  <Orders>
    <OrderId>Ex1</OrderId>
    <amount>100</amount>
  </Orders>
  <Orders>
   <OrderId>Ex1</OrderId>
   <amount>250</amount>
 </orderItem>
 <orderItem>
  <Orders>
   <OrderId>Ex2</OrderId>
   <amount>150</amount>
  <Orders>
 </orderItem> 
</order>

更新答案

var groups = doc.Descendants("order").Descendants("orderItem").Descendants("Orders")
                .GroupBy(x => (string)x.Element("OrderId"))
                .ToList();

            XElement newXml = new XElement("order");
            foreach (var group in groups)
            {
                newXml.Add(new XElement("OrderList", new object[] {
                // new XAttribute("OrderId", group.Key), // If you Need Key for Attribute add this.
                    group
            }));
            }

使用名称标记比较XML节点值并删除标记

有几个步骤:

  1. 将您的订单按id分组,然后对每个分组…
  2. 获取总金额
  3. 设置第一次订单金额为总额
  4. 删除剩余订单

代码相当简单:

var ordersById = doc.Descendants("orderItem")
    .GroupBy(x => (string) x.Element("OrderId")); // 1
foreach (var grouping in ordersById)
{
    var total = grouping
        .Sum(x => (decimal) x.Element("amount")); // 2
    grouping.First().SetElementValue("amount", total); // 3
    grouping.Skip(1).Remove(); // 4
}

听起来像是OrderIdSum(amount)转换的标准组,可以通过以下LINQ到XML查询完成:

var output =
    from order in doc.Descendants("order")
    select new XElement("order", 
        from orderItem in doc.Descendants("orderItem")
        group orderItem by (string)orderItem.Element("OrderId") into orderItems
        select new XElement("orderItem",
            new XElement("OrderId", orderItems.Key),
            new XElement("amount", orderItems.Sum(e => (int)e.Element("amount")))));                

使用xml linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:'temp'test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var groups = doc.Descendants("orderItem")
                .GroupBy(x => (string)x.Element("OrderId"))
                .Select(x => x.Select(y => new {orderId = y, amount = (int)y.Element("amount")}))
                .ToList();
            for (int groupNum = groups.Count - 1; groupNum >= 0; groupNum--)
            {
                var group = groups[groupNum];
                int total = group.Select(x => x.amount).Sum();
                for (int orderItemCount = group.Count() - 1; orderItemCount >= 0; orderItemCount--)
                {
                    var orderItem = group.Skip(orderItemCount).FirstOrDefault();
                    if (orderItemCount > 0)
                    {
                        orderItem.orderId.Remove();
                    }
                    else
                    {
                        XElement amount = orderItem.orderId.Element("amount");
                        amount.Value = total.ToString();
                    }
                }
            }
        }
    }
}