尝试使用 XML to LINQ 以正确的排序顺序将新元素添加到 XML 中

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

提问人:Andrew Truckle 提问时间:10/27/2023 最后编辑:Andrew Truckle 更新时间:10/27/2023 访问量:33

问:

我正在尝试向XML文件添加一些条目:

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>

正如你所看到的,问题是我想以正确的数字顺序将这些新项目添加到现有项目中。它们被添加到底部。

在我的代码片段中是元素。ptLangInfoeng

C# LINQ-to-XML

评论

0赞 dbc 10/27/2023
值是否已排序?元素是否也已经排序好了?talkNumber<eng><PublicTalk Number="21" ...>
0赞 Andrew Truckle 10/27/2023
@dbc 此时此刻,我将对这两个问题说“是”。
0赞 Good Night Nerd Pride 10/27/2023
你试过吗?foreach(var talkNumber in listNumbers.Reverse())
0赞 Andrew Truckle 10/27/2023
@GoodNightNerdPride我看不出这有什么帮助,因为它们仍然需要插入正确的位置,以便我的结果列表从 1 开始。ptLangInfo

答:

1赞 dbc 10/27/2023 #1

XContainer.Elements() 方法返回的不是 .因此,没有内置的方法可以使用二进制搜索将元素插入到子元素的枚举中,并假设它已经排序。IEnumerable<XElement>IList<XElement>log(n)

因此,我建议事后对它们进行排序:

// 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);

在这里演示小提琴。

评论

0赞 Andrew Truckle 10/27/2023
好的,但是为什么要从有序中删除然后添加空列表?错字?我不明白这一点。
1赞 dbc 10/27/2023
不是错别字。它是命名空间中的扩展方法:System.Xml.Linq.Extensions.Remove<T>(IEnumerable<T>),用于从其当前父级中删除元素。它是必需的,以便可以重新添加它们。请看小提琴,它确实有效。System.Xml.Linq
0赞 Andrew Truckle 10/27/2023
好的,所以类似于说(或任何正确的语法。无论哪种方式,我确认您的代码有效,并感谢您为其提供上下文的小提琴。+1ordered.Remove();ptLangInfo.Elements("PublicTalk").Remove();
1赞 dbc 10/27/2023
@AndrewTruckle = 完全正确。创建当前元素的列表,从 ptLangInfo 中删除列表,将新元素添加到列表中,对列表进行排序,然后将列表添加到 ptLangInfo 可能会更清楚。但人们似乎更喜欢更简短的答案,所以这就是我写的。
0赞 Andrew Truckle 10/27/2023
在那里学习新东西!超出我的要求。😊