2009-09-03 109 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示例。