3

I am new to LINQ. I need to return the id with the correct price information for today's date for each MPrice.

Here is an example of the 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> 

2 Answers 2

7

Here is one way of doing it:

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 

Please note that there needs to be much more error checking than this example provides. I would specifically add checking around the parsing of the datetime (perhaps by using a function that wraps DateTime.TryParseExact).

Edit: If you want to use an XDocument instead of an XElement you will need to make a subtle change to the query (notice the usage 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 don't need to use an XDocument unless you are working with the XML as a true document. In most cases, the XElement type is sufficient.

Edit #2: If you want to load the XDocument from disk then 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); } } 
Sign up to request clarification or add additional context in comments.

4 Comments

Can I do the same parsing using XDocument instead of XElement?
Still doesn't seem to work. I am using: XDocument xmlDoc = XDocument.Load("my.xml"); Now when I call the : XDocument.Parse(xml).Descendants("MPrice").Elements("Price") I receive an error with not converted XDocument to string. Any ideas?
If you have already loaded the XML into the XDocument then you don't need to call XDocument.Parse. I will edit again to demonstrate how to do it with an XML file on disk.
Thank you for your time and help. The project is almost completed and I learned a few new things. Thanks
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>(); 

This should work assuming that the id is a string. You can make it an int.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.