使用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
相关产品推荐
相关产品推荐

