如何使用LINQ to XML按正确数字顺序向XML添加新元素?
按数字顺序向XML节点插入新条目
当前代码会将新的<PublicTalk>元素直接追加到eng节点末尾,需要修改为按Number属性的数字顺序插入到对应位置。
现有代码
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>
解决方案
方案1:逐个插入到对应位置
对每个新元素,找到第一个Number值大于当前元素的节点,将新元素插入到它前面;若所有现有节点的Number都更小,则追加到末尾。修改后的代码如下:
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") ); // 找到第一个Number数值大于当前talkNumber的元素 var targetElem = ptLangInfo.Elements("PublicTalk") .FirstOrDefault(elem => int.Parse(elem.Attribute("Number").Value) > talkNumber); if (targetElem != null) { targetElem.AddBeforeSelf(newElem); } else { ptLangInfo.Add(newElem); } }
方案2:合并后整体排序(适合大量新元素)
先批量创建所有新元素,与现有元素合并后按Number排序,再重新替换eng节点下的内容:
// 批量创建新元素 var newElements = listNumbers.Select(talkNumber => 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") )); // 合并现有元素与新元素,按Number数值排序 var sortedElements = ptLangInfo.Elements("PublicTalk") .Concat(newElements) .OrderBy(elem => int.Parse(elem.Attribute("Number").Value)); // 清空原有内容,添加排序后的元素 ptLangInfo.RemoveAll(); ptLangInfo.Add(sortedElements);
注意:如果
Number属性可能存在非数字值,需要增加解析异常处理逻辑。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

