RapidXML是一个快速,轻量级的C++ XML DOM Parser,但它有一些怪癖.
我想到的最糟糕的是:
3.2字符串的所有权.
RapidXml生成的节点和属性不拥有其名称和值字符串.他们只是指着他们.这意味着在使用
xml_base::name(const Ch *)或xml_base::value(const Ch *)函数手动设置这些值时必须小心.必须注意确保传递的字符串的生命周期至少与节点/属性的生命周期一样长.实现它的最简单方法是从文档拥有的memory_pool中分配字符串.使用
memory_pool::allocate_string()功能用于此目的.
现在,我明白它是以这种方式为速度做的,但这感觉就像车祸等待发生.以下代码看起来无害,但当foo返回时,'name'和'value'超出范围,因此doc未定义.
void foo()
{
char name[]="Name";
char value[]="Value";
doc.append_node(doc.allocate_node(node_element, name, value));
}
Run Code Online (Sandbox Code Playgroud)
根据allocate_string()手动工作使用的建议,但它很容易忘记.
有没有人'增强'RapidXML来避免这个问题?
我不使用RapidXML,但也许我的方法可以解决您的问题。
我开始使用 Xerces,但除了其他一些小烦恼之外,我发现它很重,所以我转向了 CPPDOM。当我采取行动时,我决定创建一组包装类,这样我的代码就不会依赖于特定的 XML“引擎”,并且如果需要,我可以移植到另一个引擎。
我创建了自己的类来表示基本 DOM 实体(节点、文档等)。这些类在内部使用 pimpl 习惯用法来使用 CPPDOM 对象。由于我的节点对象包含“真实”节点对象(来自 CPPDOM),我可以根据需要管理任何内容,因此字符串的正确分配和取消分配不会成为问题。
由于我的代码是针对 CPPDOM 的,所以我认为它对您来说没有多大用处,但如果您愿意,我可以将其发布。
顺便说一句,如果您已经有太多使用 RapidXML 的代码,您可以在包装类中重现其接口。我没有这样做,因为使用 Xerces 的代码没有那么长,无论如何我都必须重写它。