Parsing XML data with LINQ

I am new to LINQ, and there is an urgent need to quickly complete this project. I need to return an identifier with the correct price information for today's date for each MPrice. Any advice is appreciated! Here is an example 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> 
+4
source share
2 answers

Here is one way to do this:

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

Output:

 0079 131.25 

Note that error checking should be much larger than in this example. I would specifically add a check around datetime parsing (possibly using a function that wraps DateTime.TryParseExact ).

Edit: If you want to use XDocument instead of XElement , you will need to make a slight change to the request (note the use of the Descendants method instead of the Elements method):

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

Remember that you do not need to use XDocument if you are not working with XML as a genuine document. In most cases, an XElement enough.

Edit # 2: If you want to load XDocument from disk, use this approach:

 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); } } 
+7
source
 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>(); 

This should work, assuming the identifier is a string. You can do it int.

You have to do some checks to make sure the date is correct, etc .., but this is a quick example that should work for this Xml example if the Start Date changes to 2009-9-03 or the current date of the date.

+4
source

All Articles