Trying to add new elements into XML using XML to LINQ in the right sort order

38 Views Asked by At

I am trying to add some entries to a XML file:

foreach(var talkNumber in listNumbers)
{
       var newElem = new XElement("PublicTalk",
                               new XAttribute("Number", talkNumber),
                               new XAttribute("Excluded", false),
                               new XAttribute("ExcludedFromDate", "1900-01-01"),
                               new XAttribute("Note", ""),
                               new XAttribute("TimesHeard", 0),
                               new XAttribute("LastHeard", "1900-01-01")
                              );
       ptLangInfo.Add(newElem);
}

XML

<?xml version="1.0" encoding="utf-8"?>
<PublicTalkTitles>
  <!-- English -->
  <eng>
    <PublicTalk Number="21" Excluded="false" ExcludedFromDate="1900-01-01" Note="" TimesHeard="1" LastHeard="2023-10-15" />
    <PublicTalk Number="1" Excluded="false" ExcludedFromDate="1900-01-01" Note="" TimesHeard="0" LastHeard="1900-01-01" />
    <PublicTalk Number="2" Excluded="false" ExcludedFromDate="1900-01-01" Note="" TimesHeard="0" LastHeard="1900-01-01" />
    <PublicTalk Number="3" Excluded="false" ExcludedFromDate="1900-01-01" Note="" TimesHeard="0" LastHeard="1900-01-01" />
  </eng>
</PublicTalkTitles>

The problem as you can see is that I want to add these new items in the correct numerical order to the existing ones. They get added to the bottom.

In my code snippet ptLangInfo is the eng element.

1

There are 1 best solutions below

5
dbc On BEST ANSWER

The method XContainer.Elements() returns an IEnumerable<XElement> not an IList<XElement>. As such there's no builtin log(n) way to insert an element into the enumeration of child elements using a binary search and assuming it's already sorted.

Thus I'd recommend just sorting them afterwards:

// Order the elements by the Number attribute
var ordered = ptLangInfo.Elements("PublicTalk")
    .OrderBy(e => (int?)e.Attribute("Number"))
    .ToList();
// Remove the elements from ptLangInfo using System.Xml.Linq.Extensions.Remove()
ordered.Remove(); 
// Add them back in the new order
ptLangInfo.Add(ordered);

Demo fiddle here.