You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Linq to XML按数值属性在正确位置添加新条目

按Number属性数值顺序插入XML新条目

现有C#函数SetOutlineInfo用于维护XML文件中的PublicTalk条目,支持更新已有条目或新增条目,但新增时条目会被追加到对应语言节点的末尾,无法按Number属性的数值顺序插入到正确位置。

原函数代码

public void SetOutlineInfo(string talksdatabase, int talknumber, string languageCode, bool talkExcluded, DateTime dateExcudedFrom, string excludedNote)
{
    try
    {
        XDocument doc = XDocument.Load(talksdatabase);
        var ptLang = doc.Descendants(languageCode).FirstOrDefault();
        if (ptLang != null)
        {
            var ptInfo = ptLang
                            .Descendants("PublicTalk")
                            .Where(p => p.Attribute("Number").Value == talknumber.ToString()).FirstOrDefault();
            if (ptInfo != null)
            {
                ptInfo.Attribute("Excluded").Value = talkExcluded ? "true" : "false";
                ptInfo.Attribute("ExcludedFromDate").Value = dateExcudedFrom.ToString("yyyy-MM-dd");
                ptInfo.Attribute("ExcludedNote").Value = excludedNote;
            }
            else
            {
                ptLang.Add(new XElement("PublicTalk",
                    new XAttribute("Number", talknumber),
                    new XAttribute("Excluded", talkExcluded),
                    new XAttribute("ExcludedFromDate", dateExcudedFrom.ToString("yyyy-MM-dd")),
                    new XAttribute("ExcludedNote", excludedNote)
                    ));
            }

            doc.Save(talksdatabase);
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
    }
}

解决方案实现

要实现新增时按Number数值插入到对应位置,核心是找到第一个Number值大于当前新增条目编号的元素,然后在该元素之前插入新条目;如果所有元素的Number都小于新增编号,则将条目追加到末尾。

修改后的函数代码:

public void SetOutlineInfo(string talksdatabase, int talknumber, string languageCode, bool talkExcluded, DateTime dateExcudedFrom, string excludedNote)
{
    try
    {
        XDocument doc = XDocument.Load(talksdatabase);
        var ptLang = doc.Descendants(languageCode).FirstOrDefault();
        if (ptLang != null)
        {
            var ptInfo = ptLang
                            .Elements("PublicTalk") // 改用Elements直接获取子节点,避免递归
                            .FirstOrDefault(p => int.Parse(p.Attribute("Number").Value) == talknumber);

            if (ptInfo != null)
            {
                // 更新已有条目
                ptInfo.Attribute("Excluded").Value = talkExcluded ? "true" : "false";
                ptInfo.Attribute("ExcludedFromDate").Value = dateExcudedFrom.ToString("yyyy-MM-dd");
                ptInfo.Attribute("ExcludedNote").Value = excludedNote;
            }
            else
            {
                // 创建新条目
                var newTalk = new XElement("PublicTalk",
                    new XAttribute("Number", talknumber),
                    new XAttribute("Excluded", talkExcluded ? "true" : "false"), // 统一字符串格式
                    new XAttribute("ExcludedFromDate", dateExcudedFrom.ToString("yyyy-MM-dd")),
                    new XAttribute("ExcludedNote", excludedNote)
                );

                // 找到第一个Number值大于当前编号的元素
                var firstLargerTalk = ptLang.Elements("PublicTalk")
                    .FirstOrDefault(t => int.Parse(t.Attribute("Number").Value) > talknumber);

                if (firstLargerTalk != null)
                {
                    // 在目标元素前插入新条目
                    firstLargerTalk.AddBeforeSelf(newTalk);
                }
                else
                {
                    // 所有元素编号都更小,追加到末尾
                    ptLang.Add(newTalk);
                }
            }

            doc.Save(talksdatabase);
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
    }
}

关键修改说明

  • 优化条目查询:将Descendants改为Elements,直接获取语言节点下的PublicTalk子节点,避免不必要的递归查询。
  • 统一属性格式:新增条目时将Excluded属性统一转换为字符串"true"/"false",和更新逻辑保持一致。
  • 定位插入位置:通过LINQ找到第一个编号大于当前新增值的元素,使用AddBeforeSelf插入到该元素之前;如果没有找到,则追加到节点末尾。

测试验证

  • 初始XML包含Number="47"的条目,新增Number="1"时,会插入到Number="47"条目之前。
  • 若已有Number="10"、Number="20"的条目,新增Number="15"时,会插入到两者之间。
  • 新增Number="50"时,会追加到所有条目末尾。

内容的提问来源于stack exchange,提问作者Andrew Truckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:40:32