2009-09-03 209 views
4

我是LINQ的新手,急需完成這個項目。我需要爲每個MPrice的今日日期返回帶有正確價格信息的ID。任何建議,非常感謝!下面是XML的例子:用LINQ解析XML數據

<Pricing> 
<MPrice> 
    <Id>0079</Id> 
     <Price> 
     <Price>31.25</Price> 
     <StartDt>2009-8-01</StartDt> 
     <EndDt>2009-08-26</EndDt> 
     </Price> 
     <Price> 
     <ListPrice>131.25</ListPrice> 
     <StartDt>2009-08-26</StartDt> 
     <EndDt>9999-12-31</EndDt> 
     </Price> 
    </MPrice> 
    <MPrice> 
    <Id>0081</Id> 
     <Price> 
     <Price>131.25</Price> 
     <StartDt>2009-8-01</StartDt> 
     <EndDt>2009-08-26</EndDt> 
     </Price> 
     <Price> 
     <ListPrice>231.25</ListPrice> 
     <StartDt>2009-08-26</StartDt> 
     <EndDt>9999-12-31</EndDt> 
     </Price> 
    </MPrice> 
</Pricing> 

回答

7

這裏是做這件事的一種方法:

using System; 
using System.Linq; 
using System.Xml.Linq; 

class Program 
{ 
    static void Main() 
    { 
     String xml = @"<Pricing> 
      <MPrice> 
       <Id>0079</Id> 
       <Price> 
       <Price>31.25</Price> 
       <StartDt>2009-8-01</StartDt> 
       <EndDt>2009-08-26</EndDt> 
       </Price> 
       <Price> 
       <ListPrice>131.25</ListPrice> 
       <StartDt>2009-08-26</StartDt> 
       <EndDt>9999-12-31</EndDt> 
       </Price> 
      </MPrice> 
      </Pricing>"; 

     var priceInfo = from e in XElement.Parse(xml).Elements("MPrice").Elements("Price") 
       let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value) 
       let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value) 
       where start < DateTime.Now && end > DateTime.Now 
       select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value }; 

     Console.WriteLine(priceInfo.FirstOrDefault().Id); 
     Console.WriteLine(priceInfo.FirstOrDefault().ListPrice); 
    } 
} 

輸出:

0079 
131.25 

請注意,需要有更多的錯誤檢查比這個例子提供。我會特別添加檢查日期時間的解析(可能通過使用包裝DateTime.TryParseExact的函數)。

編輯:如果你想使用XDocument代替XElement,你將需要對查詢了微妙的變化(注意Descendants方法,而不是Elements方法的用法):

var priceInfo = from e in XDocument.Parse(xml).Descendants("MPrice").Elements("Price") 
     let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value) 
     let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value) 
     where start < DateTime.Now && end > DateTime.Now 
     select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value }; 

請記住,除非您將XML用作真實文檔,否則不需要使用XDocument。在大多數情況下,XElement類型就足夠了。

編輯#2:如果你想從磁盤加載XDocument然後用這個辦法:

using System; 
using System.Linq; 
using System.Xml.Linq; 

class Program 
{ 
    static void Main() 
    { 
     XDocument document = XDocument.Load(@"d:\test.xml"); 

     var priceInfo = from e in document.Descendants("MPrice").Elements("Price") 
       let start = DateTime.Parse(e.Descendants("StartDt").FirstOrDefault().Value) 
       let end = DateTime.Parse(e.Descendants("EndDt").FirstOrDefault().Value) 
       where start < DateTime.Now && end > DateTime.Now 
       select new { Id = e.Parent.Element("Id").Value, ListPrice = e.Element("ListPrice").Value }; 

     Console.WriteLine(priceInfo.FirstOrDefault().Id); 
     Console.WriteLine(priceInfo.FirstOrDefault().ListPrice); 
    } 
} 
+0

我能做使用的XDocument代替的XElement相同的解析? – SDC 2009-09-03 17:37:49

+1

是的,你可以!請參閱我的編輯。 – 2009-09-03 17:58:29

+0

仍似乎沒有工作。我正在使用: XDocument xmlDoc = XDocument.Load(「my.xml」); 現在,當我調用: XDocument.Parse(xml).Descendants(「MPrice」)。Elements(「Price」) 我收到一個錯誤,未將XDocument轉換爲字符串。有任何想法嗎? – SDC 2009-09-03 19:57:56

4
string id = yourDocument 
       .Descendants("Pricing") 
       .Descendants<XElement>("MPrice") 
       .Where<XElement>(i => i.Descendants("Price") 
             .Descendants<XElement>("StartDt") 
             .Select<XElement, DateTime>(s => DateTime.Parse(s.Value)) 
             .FirstOrDefault<DateTime>().Date == DateTime.Now.Date) 
       .Select<XElement, string>(i => i.Descendants("Id").FirstOrDefault<XElement>().Value) 
       .FirstOrDefault<string>(); 

這應該假設ID是一個字符串。你可以使它成爲一個整數。

你應該做一些檢查,以確保日期是正確的等..。 。 ,但這是一個快速示例,如果開始日期更改爲2009-9-03或當前日期日期,則該示例應該適用於給定的Xml示例。