I have XML like that
<?xml version="1.0" ?>
<customers>
<customer>
<date>22 Aug 2014</date>
<name>Kevin Anders</name>
<phone>555.555.5555</phone>
</customer>
<customer>
<date>23 Aug 2014</date>
<name>Staci Richard</name>
<phone>555.122.1552</phone>
</customer>
<customer>
<date>25 Aug 2014</date>
</customer>
</customers>
In the XML some nodes are missing but date node is present in every element. I have around 200 of nodes but i want to parse the xml based on date and just need to return top 4 dates. For example today is 16 june then my xml get the latest date node and return next three days matching nodes. I am able to parse the nodes but not sure how to return top nodes based on date
public static IEnumerable<Customer> StreamBooks(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
string name = null;
string phone = null;
reader.MoveToContent();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "customer")
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "name")
{
name = reader.ReadString();
break;
}
}
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "phone")
{
phone = reader.ReadString();
break;
}
}
yield return new Customer() { Name = name, Phone = phone };
}
}
}
}
I'd start off by removing your current code to retrieve a sequence of customers, and instead just use LINQ to XML:
var customers = XDocument.Load(uri)
.Root.Elements("customer")
.Select(x => new Customer {
Date = (DateTime) x.Element("date"),
Name = (string) x.Element("name"),
Phone = (string) x.Element("phone")
});
This requires you to change your date format to "yyyy-MM-dd" which is a standard XML date format. (So "2014-08-23" instead of "23 Aug 2014" for example.)
If you have to keep the existing date format, you can use:
var customers = XDocument.Load(uri)
.Root.Elements("customer")
.Select(x => new Customer {
Date = DateTime.ParseExact(x.Element("date").Value, "d MMM yyyy",
CultureInfo.InvariantCulture),
Name = (string) x.Element("name"),
Phone = (string) x.Element("phone")
});
You might also want to add a call to ToList()
after Select
, if you want the whole list of customers for other reasons.
After this, the fact that the original data source was XML is irrelevant. You can then use OrderByDescending
to sort by date with the most recent first, and Take
to limit the results:
var recentCustomers = customers.OrderByDescending(c => c.Date)
.Take(4);
LINQ is a very useful technique for querying data. I strongly recommend that you learn more about is - search for information on MSDN, tutorials etc.
See more on this question at Stackoverflow