【问题标题】:moving (not copying) nodes using pugixml and rapidxml使用 pugixml 和 rapidxml 移动(不复制)节点
【发布时间】:2014-08-10 13:45:38
【问题描述】:

我正在寻找一个支持 DOM 接口的 XML 库。性能对我来说很重要,所以我目前正在研究 rapidxml 和 pugixml。

问题是我的应用程序需要修改 DOM 树,包括移动节点。而且我看不到这样做的直接方法(无论是使用 rapidxml 还是使用 pugixml)。看来我需要复制/克隆节点,如果我要移动的子树很深,这可能会导致大量复制操作。

有没有更有效的方法(使用 rapidxml 或 pugixml)(例如交换指针等)?如果没有,是否有任何其他轻量级库允许这样做?

谢谢!

【问题讨论】:

  • Pugixml 数据结构支持在同一文档中进行高效移动,但这些操作尚未实现。我今天会努力做到的。

标签: c++ xml rapidxml pugixml


【解决方案1】:

pugixml 现在(截至一个小时前)能够廉价地移动节点子树 - 请参阅 xml_node::prepend_move/append_move/insert_move_before/insert_move_after。

请注意,这些操作不是恒定时间 - 或者更确切地说,操作本身是,但有一个验证步骤可防止在其自己的子树内移动节点(这会导致节点与树的其余部分分离并导致内存泄漏);这一步必须遍历新节点位置的祖先链,使得移动 O(logN)。

【讨论】:

  • 您好 zeuxcg,感谢您的快速回复!我已经看到了主干的变化。我想我可以通过注释掉allow_move()的调用来实现O(1)而不是O(logN),不是吗? (风险自负)。其次,是否可以将节点移出文档(可能通过将其放在临时文档上)然后将其放回原来的位置(这样做的原因是我需要支持'undo'/'在我的应用程序中重做操作)。再次感谢!我非常感谢您的更改
  • 注释掉 allow_move() 的调用将禁用 O(logN) 验证和防止将节点从一个文档移动到另一个文档的保护。之所以不允许跨文档移动,是因为节点数据的生命周期与文档的生命周期是绑定的。只要您保持两个文档的生命周期相同,我认为这实际上应该是安全的,但是您也可以考虑将撤消堆栈存储在同一文档的根级节点中。
  • 嗨 zeuxcg。关于您的最后评论并将对象从一个文档移动到另一个文档。我从您之前的评论中了解到,两个文档的生命周期必须保持不变。假设我已将所有节点从 Doc1 移动到 Doc2,删除 Doc1 不安全吗?
  • 不,即使您将所有节点都移动到 doc2,删除 doc1 也是不安全的,因为文档管理所有使用的内存结构(特别是具有初始解析文本数据和小分配页面的文档缓冲区)文档中的节点(注意:这些内部细节的存在正是库存移动实现不允许跨文档移动的原因——它们太容易出错了)。
猜你喜欢
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
相关资源
最近更新 更多