使用pugixml和rapidxml移动(而不是复制)节点

4
我正在寻找一个支持DOM接口的XML库,性能对我很重要,所以目前我正在考虑rapidxml和pugixml。
问题是我的应用程序需要修改DOM树,包括移动节点。我无法找到直接的方法来做这件事(无论是使用rapidxml还是pugixml)。似乎我需要复制/克隆节点,如果我想要移动的子树非常深,这可能会导致大量的复制操作。
是否有更有效的方法来处理这个问题(无论是使用rapidxml还是pugixml)(例如交换指针等)?如果没有,是否有其他轻量级库可以实现这一点?
谢谢!

Pugixml数据结构支持在同一文档内高效移动,但这些操作尚未实现。我会尝试在今天完成它。 - zeuxcg
1个回答

4

pugixml目前(截至一小时前)具有廉价移动节点子树的能力-请参见xml_node::prepend_move/append_move/insert_move_before/insert_move_after。

请注意,这些操作不是常数时间 - 或者说操作本身是常数时间,但有一个验证步骤,防止将节点移动到其自己的子树中(这会导致该节点与树的其他部分分离并引起内存泄漏),该步骤必须遍历新节点位置的祖先链,使得移动变为O(logN)。


嗨zeuxcg,感谢您的快速回复!我已经在主干中看到了更改。如果我注释掉allow_move()的调用,我是否可以实现O(1)而不是O(logN)?(并承担自己的风险)。其次,是否可能将节点移出文档(可能通过将其放置在临时文档上),然后将其放回原来的位置(这样做的原因是我需要支持我的应用程序中的“撤消”/“重做”操作)。再次感谢!我真的很感激您的更改。 - user1192525
注释掉allow_move()的调用将禁用O(logN)验证和防止节点从一个文档移动到另一个文档的保护。不允许跨文档移动的原因是节点数据的生命周期与文档的生命周期绑定在一起。只要您保持两个文档的生命周期相同,我认为这实际上是安全的,但您也可以考虑在同一文档中的根级节点中存储撤消堆栈。 - zeuxcg
你好,zeuxcg。关于你上一条评论中提到的将一个对象从一个文档移动到另一个文档的问题。我理解你之前的评论是指这两个文档的生命周期必须保持不变。假设我已经将Doc1中的所有节点移动到了Doc2中,那么删除Doc1应该是安全的吧? - user1192525
不,即使您将所有节点移动到doc2,删除doc1也是不安全的,因为文档管理内存结构(特别是带有初始解析文本数据和小分配页面的文档缓冲区),这些结构被文档中的所有节点使用(请注意:这些内部细节的存在正是股票移动实现禁止跨文档移动的原因-它们太容易出错了)。 - zeuxcg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接