Reputation: 22914
Im using LINQ to XML to delete and inserts tags into an xml document. One situation I often encounter is that I have a preference of where I want to insert a particular tag but that preference can't always be met. For example here I'd prefer to insert it right after the last element with the same CalendarCode:
elements = from e in calendarDocument.Descendants("ExceptionalSessions") where e.Element("CalendarCode") == calendarCode select e;
elements.Last().AddAfterSelf(sessionElement);
However sometimes the element to be inserted is the first of its kind in that document with that CalendarCode so the extra condition:
where e.Element("CalendarCode") == calendarCode
will create an empty result set. In that case I'd like to use a query without that additional condition. This is a one time thing though, after inserting an element with that calendar code I'd like the NEXT element with the same CalendarCode to be inserted after the first one... in that case I'd want to use the query with that additional condition.
I tried a few ways to solve this but they all look very crude and possibly inefficient and I couldnt help but think there's a better way.
Can anyone give me an idea if they ever encountered this.
Upvotes: 1
Views: 399
Reputation: 11396
One option is to evaluate the condition and decide the target prior to adding it. Using a separate method for clarity, possibly something like this (not tested):
private XElement GetCalendarTargetNode(XElement source, XElement calendarCode)
{
var exceptionalSessions = source.Descendants("ExceptionalSessions");
return exceptionalSessions.LastOrDefault(e => e.Element("CalendarCode") == calendarCode) ?? exceptionalSessions.Last();
}
Or a slightly different implementation:
private XElement GetCalendarTargetNode(XElement source, XElement calendarCode)
{
var exceptionalSessions = source.Descendants("ExceptionalSessions");
return exceptionalSessions.Where(e => e.Element("CalendarCode") == calendarCode).DefaultIfEmpty(exceptionalSessions.Last()).Last();
}
And use it:
var target = GetCalendarTargetNode(calendarDocument, calendarCode);
target.AddAfterSelf(sessionElement);
EDIT: Or a simplified version without using extra methods:
var exceptionalSessions = calendarDocument.Descendants("ExceptionalSessions");
var target = exceptionalSessions.Where(e => e.Element("CalendarCode") == calendarCode)
.DefaultIfEmpty(exceptionalSessions.Last());
target.Last().AddAfterSelf(sessionElement);
Upvotes: 2