2010-01-30 16 views
2

所以我很接近這個,但是當我的ItemPrice元素(例如稅)下的組件之一丟失,那麼我的整個訂單/行不返回。如果像「稅」這樣的組件有時會丟失,我可以做什麼?仍然有問題使用LINQ來查詢我的XML

XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SettlementReport> 
<Order> 
    <AmazonOrderID>105-6982537-6258888</AmazonOrderID> 
    <ShipmentID>MyShipmentIDTest1234</ShipmentID> 
    <MarketplaceName>Amazon.com</MarketplaceName> 
    <Fulfillment> 
     <MerchantFulfillmentID>MyTestFulFillID12345</MerchantFulfillmentID> 
     <PostedDate>2008-12-15T19:33:04+00:00</PostedDate> 
     <Item> 
      <AmazonOrderItemCode>13350774331938</AmazonOrderItemCode> 
      <SKU>U1409</SKU> 
      <Quantity>1</Quantity> 
      <ItemPrice> 
       <Component> 
         <Type>Principal</Type> 
         <Amount currency="USD">0.15</Amount> 
        </Component> 
       <Component> 
         <Type>Tax</Type> 
         <Amount currency="USD">0.02</Amount> 
        </Component> 
       </ItemPrice> 
      </Item> 
      <Item> 
      <AmazonOrderItemCode>13350774331939</AmazonOrderItemCode> 
      <SKU>U14010</SKU> 
      <Quantity>2</Quantity> 
      <ItemPrice> 
       <Component> 
         <Type>Principal</Type> 
         <Amount currency="USD">0.30</Amount> 
        </Component> 
       <Component> 
         <Type>Tax</Type> 
         <Amount currency="USD">0.04</Amount> 
        </Component> 
       </ItemPrice> 
      </Item> 
     </Fulfillment> 
    </Order> 
<Order> 
    <AmazonOrderID>105-6982537-6259999</AmazonOrderID> 
    <ShipmentID>MyShipmentIDTest1234</ShipmentID> 
    <MarketplaceName>Amazon.com</MarketplaceName> 
    <Fulfillment> 
     <MerchantFulfillmentID>MyTestFulFillID12345</MerchantFulfillmentID> 
     <PostedDate>2008-12-15T19:33:04+00:00</PostedDate> 
     <Item> 
      <AmazonOrderItemCode>13350774331940</AmazonOrderItemCode> 
      <SKU>U1409</SKU> 
      <Quantity>1</Quantity> 
      <ItemPrice> 
       <Component> 
         <Type>Principal</Type> 
         <Amount currency="USD">0.40</Amount> 
        </Component> 
       <Component> 
         <Type>Tax</Type> 
         <Amount currency="USD">0.15</Amount> 
        </Component> 
       </ItemPrice> 
      </Item> 
      <Item> 
      <AmazonOrderItemCode>13350774331941</AmazonOrderItemCode> 
      <SKU>U14010</SKU> 
      <Quantity>2</Quantity> 
      <ItemPrice> 
       <Component> 
         <Type>Principal</Type> 
         <Amount currency="USD">0.50</Amount> 
        </Component> 
       </ItemPrice> 
      </Item> 
     </Fulfillment> 
    </Order>  

我的代碼:

XDocument customer = XDocument.Load(@"C:\LinqToXML.xml"); 

      var orders = from amznorders in customer.Root.Elements("Order") 
         from amznfulfill in amznorders.Elements("Fulfillment") 
         from amznitems in amznfulfill.Elements("Item") 
         from amznitemprc1 in amznitems.Elements("ItemPrice").Elements("Component") 
         from amznitemprc2 in amznitems.Elements("ItemPrice").Elements("Component") 
         let amznitemprinc = amznitemprc1.Element("Amount") 
         where (string)amznitemprc1.Element("Type") == "Principal" 
         let amznitemprtax = amznitemprc2.Element("Amount") 
         where (string)amznitemprc2.Element("Type") == "Tax" 
         select new 
         { 
          OrderNumber = (string)amznorders.Element("AmazonOrderID"), 
          ItemNumber = (string)amznitems.Element("AmazonOrderItemCode"), 
          Qty = amznitems == null ? "0" : (string)amznitems.Element("Quantity"), 
          PriceAmount = amznitemprinc == null ? String.Empty : (string)amznitemprinc, 
          TaxAmount = amznitemprtax == null ? String.Empty : (string)amznitemprtax 
         }; 


      foreach (var order in orders) 
      { 
       Console.WriteLine("Order: {0} ItemNumber: {1} QTY: {2} {3} {4}", order.OrderNumber, order.ItemNumber, order.Qty,order.PriceAmount,order.TaxAmount); 

      } 

回答

0

如何:

var orders = from amznorders in customer.Root.Elements("Order") 
      from amznfulfill in amznorders.Elements("Fulfillment") 
      from amznitems in amznfulfill.Elements("Item") 
      let amznitemprcs = amznitems.Elements("ItemPrice").Elements("Component").Select(element => new { 
       Type = element.Element("Type").Value, 
       Amount = element.Element("Amount").Value 
      }) 
      select new 
      { 
       OrderNumber = amznorders.Element("AmazonOrderID").Value, 
       ItemNumber = amznitems.Element("AmazonOrderItemCode").Value, 
       Qty = amznitems.Element("Quantity").Value, 
       PriceAmount = amznitemprcs.Where(x => x.Type == "Principal").Select(x => x.Amount).FirstOrDefault() ?? string.Empty, 
       TaxAmount = amznitemprcs.Where(x => x.Type == "Tax").Select(x => x.Amount).FirstOrDefault() ?? string.Empty, 
      }; 

結果:

Order: 105-6982537-6258888 ItemNumber: 13350774331938 QTY: 1 0.15 0.02 
Order: 105-6982537-6258888 ItemNumber: 13350774331939 QTY: 2 0.30 0.04 
Order: 105-6982537-6259999 ItemNumber: 13350774331940 QTY: 1 0.40 0.15 
Order: 105-6982537-6259999 ItemNumber: 13350774331941 QTY: 2 0.50 
+0

我很好奇你的解決方案與我的礦工之間的性能差異,所以我做了一點基準測試。我的解決方案在3秒時速度稍微快一點,而對於100萬次迭代,時間爲4.7秒。神聖的廢話,我猜perf是不是真的這些類型的查詢問題。 – 2010-01-30 20:00:51

0

就像Linq一樣棒,我不相信這是查詢XML文檔的最佳解決方案。這是一個使用Linq和XPath組合的變體

var items = from li in doc.XPathSelectElements("/SettlementReport/Order/Fulfillment/Item") 
     select new { 
     OrderNumber = li.XPathSelectElement("../..").Element("AmazonOrderID").Value, 
     ItemNumber = li.Element("AmazonOrderItemCode").Value, 
     Quantity = li.Element("AmazonOrderItemCode").Value, 
     PriceAmount = li.XPathSelectElement("ItemPrice/Component[Type='Principal']") != null ? li.XPathSelectElement("ItemPrice/Component[Type='Principal']").Element("Amount").Value : string.Empty, 
     TaxAmount = li.XPathSelectElement("ItemPrice/Component[Type='Tax']") != null ? li.XPathSelectElement("ItemPrice/Component[Type='Tax']").Element("Amount").Value : string.Empty 
     };