2016-08-13 56 views
0

我有XML實例比較使用名稱標籤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標記值然後添加量標籤和刪除新添加的標籤。

結果輸出我需要應該像下面

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

將訂單值應該改變。

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

我不知道接下來要做什麼。

在此先感謝。

UPDATE

我的新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> 

如果將訂單一樣那麼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 
      })); 
      } 
+1

簡稱組你'orderItems'通過'OrderId'並總結'金額' –

回答

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

1

聽起來像是由OrderId標準組Sum(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")))));     
+0

我可以知道什麼變量是e嗎? – rAm

+0

'orderItems'類型是'IGrouping ',它依次是'IEnumerable ',所以'e'類型是'XElement'。 'orderItems'包含一個共享相同密鑰的'XElement'的集合(您的情況爲「OrderId」) –

+0

好的謝謝,Will Check。 – rAm

0

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

     } 
    } 
}