【问题标题】:Compare XML Node Values using Name Tag and Remove the Tag使用名称标签比较 XML 节点值并删除标签
【发布时间】:2016-08-13 07:48:39
【问题描述】:

我有 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 值应更改。

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

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

提前致谢。

更新

我的新 XML 如下所示

<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 标记添加到匹配标记。 结果我需要如下所示

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

【问题讨论】:

  • 只需将orderItemsOrderId 分组并总结amount

标签: c# xml linq


【解决方案1】:

有几个步骤:

  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
}

请参阅this fiddle 以获得工作演示。

【讨论】:

    【解决方案2】:

    听起来像是OrderIdSum(amount) 转换的标准组,可以通过以下LINQ to 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")))));                
    

    【讨论】:

    • 我可以知道e是什么变量吗?
    • orderItems 类型是IGrouping&lt;string, XElement&gt;,而IEnumerable&lt;XElement&gt;,所以e 类型是XElementorderItems 包含 XElement 的集合,它们共享相同的密钥(在您的情况下为“OrderId”)
    • 好的,谢谢,会检查。
    • 你能看到我更新的问题并帮我解决吗?
    • 当然我或其他人可以帮助你。但我建议您将新要求作为新问题发布,因为“更新”基本上会使所有当前答案无效,这违反了网站规则。
    【解决方案3】:

    使用 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();
                        }
                    }
                }
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 2016-11-12
      • 1970-01-01
      相关资源
      最近更新 更多