I have a XML Structure that looks like this.
<sales>
<item name="Games" sku="MIC28306200" iCat="28"
sTime="11/26/2008 8:41:12 AM"
price="1.00" desc="Item Name" />
<item name="Games" sku="MIC28307100" iCat="28"
sTime="11/26/2008 8:42:12 AM"
price="1.00" desc="Item Name" />
...
</sales>
I am trying to find a way to SORT the nodes based on the sTime attribute which is a DateTime.ToString() value. The trick is I need to keep the Nodes in tact and for some reason I can't find a way to do that. I'm fairly certain that LINQ and XPath have a way to do it, but I'm stuck because I can't seem to sort based on DateTime.ToString() value.
XPathDocument saleResults = new XPathDocument(@"temp/salesData.xml");
XPathNavigator navigator = saleResults.CreateNavigator();
XPathExpression selectExpression = navigator.Compile("sales/item/@sTime");
selectExpression.AddSort("@sTime",
XmlSortOrder.Descending,
XmlCaseOrder.None,
"",
XmlDataType.Number);
XPathNodeIterator nodeIterator = navigator.Select(selectExpression);
while( nodeIterator.MoveNext() )
{
string checkMe = nodeIterator.Current.Value;
}
I also need to maintain a pointer to the NODE to retrieve the values of the other attributes.
Perhaps this isn't a simple as I thought it would be.
Thanks.
Solution: Here's what I ended up using. Taking the selected answer and the IComparable class this is how I get the XML nodes sorted based on the sTime attribute and then get the all the attributes into the appropriate Arrays to be used later.
XPathDocument saleResults = new XPathDocument(@"temp/salesData.xml");
XPathNavigator navigator = saleResults.CreateNavigator();
XPathExpression selectExpression = navigator.Compile("sales/item");
XPathExpression sortExpr = navigator.Compile("@sTime");
selectExpression.AddSort(sortExpr, new DateTimeComparer());
XPathNodeIterator nodeIterator = navigator.Select(selectExpression);
int i = 0;
while (nodeIterator.MoveNext())
{
if (nodeIterator.Current.MoveToFirstAttribute())
{
_iNameList.SetValue(nodeIterator.Current.Value, i);
}
if (nodeIterator.Current.MoveToNextAttribute())
{
_iSkuList.SetValue(nodeIterator.Current.Value, i);
}
...
nodeIterator.Current.MoveToParent();
i++;
}
Here you go:
XmlDocument myDoc = new XmlDocument();
myDoc.LoadXml(@"
<sales>
<item name=""Games""
sku=""MIC28306200""
iCat=""28""
sTime=""11/26/2008 8:41:12 AM""
price=""1.00""
desc=""Item Name"" />
<item name=""Games""
sku=""MIC28307100""
iCat=""28""
sTime=""11/26/2008 8:42:12 AM""
price=""1.00""
desc=""Item Name"" />
</sales>
");
var sortedItems = myDoc.GetElementsByTagName("item").OfType<XmlElement>()
.OrderBy(item => DateTime.ParseExact(item.GetAttribute("sTime"), "MM/dd/yyyy h:mm:ss tt", null));
foreach (var item in sortedItems)
{
Console.WriteLine(item.OuterXml);
}
That's a Console app that works perfectly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With