Trying to sort an xml file based on a Time Field (soonest first)... a snippet of the xml is here: (The element I want to order on is TimeEventStart)
<Bookings>
<Data>
<BookingDate>2015-03-02T00:00:00</BookingDate>
<StartBookingDate>2015-03-02T00:00:00</StartBookingDate>
<RoomDescription>The room</RoomDescription>
<TimeEventStart>6:00 PM</TimeEventStart>
<TimeEventEnd>2015-03-02T20:00:00</TimeEventEnd>
<GroupName>Group Council</GroupName>
<EventName>Some cool event</EventName>
<SetupTypeDescription>SPECIAL</SetupTypeDescription>
<SetupCount>30</SetupCount>
<ReservationID>64352</ReservationID>
<EventCoordinator>ERS</EventCoordinator>
<GroupID>124151</GroupID>
<VIP xml:space="preserve"> </VIP>
<VIPEvent>false</VIPEvent>
<ClosedAllDay>false</ClosedAllDay>
....
</Data>
<Data>
.... more like above ...
</Data>
</Bookings>
First off I was using this previous answer as a guide:
static void SortFeed(String resMain)
{
XDocument xmlSorted = XDocument.Parse(resMain);
foreach (var trans in xmlSorted.Descendants("Data"))
{
trans.ReplaceAll(trans.Elements().OrderBy(x => DateTime.Parse(x.Element("TimeEventStart").Value)).ToArray());
}
string newXml = xmlSorted.ToString();
Console.WriteLine("Done:");
Console.WriteLine(newXml);
}
This runs but gives an error in the
DateTime.Parse(x.Element("TimeEventStart").Value)
the error was nullreference exception unhandled.
I think I know what is going on, its looking to sort on TimeEventStart but is finding something else instead, I thought this would just only order by on that element if it found it, I must be mistaken. Having no experience with Linq (and apparently juggling xml files), I am curious what piece I am missing or if maybe I started my parsing off in the wrong area? (.Decendants? )
You're going in one level too deep - trans
is already a Data
element, you're then ordering the elements within Data
... by a TimeEventStart
element within each of those subelements... and that doesn't exist, because TimeEventStart
is a direct element within Data
. I suspect you want to take out your foreach
loop:
var doc = XDocument.Parse(resMain);
var root = xmlSorted.Root;
var sortedData = root.Elements
.OrderBy(data => DateTime.Parse(data.Element("DateTimeStart").Value))
.ToArray();
root.ReplaceAll(sortedData);
However, you might still have a problem, due to the value of DateTimeStart
- you've got just 6:00 PM
which doesn't look like a date/time to me. The DateTimeEnd
value looks like a proper ISO-8601 date/time... indeed, you could just cast such an XElement
to DateTime
, e.g.
var sortedData = root.Elements
.OrderBy(data => (DateTime) data.Element("DateTimeEnd"))
.ToArray();
... but that's obviously ordering by the end rather than by the start. If that's really what your data looks like, and you really want to order by it, you'll need to think a bit about what it actually means, because it's not a date and time.
See more on this question at Stackoverflow