Search code examples
c#linq-to-xmlxelement

Is it possible to convert this foreach loop into a LINQ-to-XML loop?


I originally asked this question (Can we automatically add a child element to an XElement in a sortable manner?) and it was closed as a duplicate (how to add XElement in specific location in XML Document).

This is teh code that I have at the moment:

bool bInserted = false;
foreach (var weekDB in xdoc.Root.Elements())
{
    DateTime datWeekDB = DateTime.ParseExact(weekDB.Name.LocalName, "WyyyyMMdd", CultureInfo.InvariantCulture);
    if (datWeekDB != null && datWeekDB.Date > historyWeek.Week.Date)
    {
        // Insert here
        weekDB.AddBeforeSelf(xmlHistoryWeek);
        bInserted = true;
        break;
    }
}
if (!bInserted)
    xdoc.Root.Add(xmlHistoryWeek);

It works fine. But I wondered if I can use LINQ to acheive the same thing? The linked answer suggests:

Search element you want to add and use Add method as shown below

xDoc.Element("content")
    .Elements("item")
    .Where(item => item.Attribute("id").Value == "2").FirstOrDefault()
    .AddAfterSelf(new XElement("item", "C", new XAttribute("id", "3")));

But I don't understand how to end up with logic like that based on my codes logic.


Solution

  • I think the best way to think about it is: you are going to use LINQ to find a specific element. Then you will insert into the document based on what you found.

    So something like this:

    var targetElement = xdoc.Root.Elements()
        .Where(weekDB => {
            DateTime datWeekDB = DateTime.ParseExact(weekDB.Name.LocalName, "WyyyyMMdd", CultureInfo.InvariantCulture);
            return datWeekDB != null && datWeekDB.Date > historyWeek.Week.Date;
        })
        .FirstOrDefault();
    if (targetElement == null)
    {
        xdoc.Root.Add(xmlHistoryWeek);
    }
    else
    {
        targetElement.AddBeforeSelf(xmlHistoryWeek);
    }