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

使用pugixml排序XML节点后_weekNode未更新的问题求助

问题分析

你的代码核心问题出在sort()函数的实现上:

  • 执行_rootNode.remove_child(node)后,原Week节点已脱离文档树;
  • 后续调用_rootNode.append_copy(node)是创建原节点的副本添加回文档,但全局变量_weekNode仍指向被移除的旧节点(该节点已不属于文档结构);
  • 因此fillWeek()往这个无效旧节点添加Activity,不会出现在最终保存的XML中。
解决方案

提供两种可行修复方式,优先推荐第一种(减少全局变量依赖,代码更健壮):

方案1:排序后重新查找目标节点

排序后根据Week节点的From属性值重新定位目标节点,再执行填充操作:

// 修改fillWeek,改为接收xml_node参数,不再依赖全局变量
void fillWeek(pugi::xml_node weekNode)
{
    auto activity = weekNode.append_child("Activity");
    activity.append_attribute("Type").set_value("0");
}

int main()
{
    loadXML();

    std::string targetFrom = "08/10"; // 记录需要填充的Week节点标识
    makeWeek("15/10","19/10");
    makeWeek(targetFrom,"12/10");

    sort();

    // 排序后重新查找目标节点
    pugi::xml_node targetWeek = _rootNode.find_child_by_attribute("Week", "From", targetFrom.c_str());
    if (targetWeek) {
        fillWeek(targetWeek);
    }

    _doc.save_file("Test.xml");

    return 0;
}

方案2:排序时移动节点而非复制

pugixml支持直接移动节点(无需复制),仅改变节点在文档中的位置,原节点引用保持有效。修改sort()函数:

void sort()
{
    std::vector<pugi::xml_node> nodesToSort;

    for (pugi::xml_node node = _rootNode.first_child(); node; node = node.next_sibling())
    {
        nodesToSort.push_back(node);
    }

    std::sort(nodesToSort.begin(), nodesToSort.end(), compareNodesByAttribute);

    // 移除所有节点(节点本身仍存在,仅脱离父节点)
    for (const pugi::xml_node& node : nodesToSort)
    {
        _rootNode.remove_child(node);
    }

    // 直接追加原节点(移动操作,而非复制)
    for (pugi::xml_node node : nodesToSort)
    {
        _rootNode.append_child(node); // 使用append_child替代append_copy
    }
}

这种方式下_weekNode仍指向原Week节点(仅位置变更),无需修改其他代码即可让fillWeek()正常工作。

额外建议

尽量减少全局变量的使用(如_weekNode),改用参数传递节点引用,可避免类似引用失效问题,提升代码可维护性。

内容的提问来源于stack exchange,提问作者Bo Halim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:45:11