7

RapidXML是一个快速、轻量级的 C++ XML DOM 解析器,但它有一些怪癖。

在我看来,最糟糕的是:

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));
}

按手册使用的建议allocate_string()有效,但很容易忘记。

有没有人“增强”RapidXML 来避免这个问题?

4

1 回答 1

1

我不使用 RapidXML,但也许我的方法可以解决您的问题。

我开始使用 Xerces,但我发现它很重,除了其他一些小烦恼,所以我转向了 CPPDOM。当我采取行动时,我决定创建一组包装类,这样我的代码就不会依赖于特定的 XML“引擎”,并且可以在需要时移植到另一个。

我创建了自己的类来表示基本的 DOM 实体(节点、文档等)。这些类在内部使用 pimpl 习惯用法来使用 CPPDOM 对象。由于我的节点对象包含“真实”节点对象(来自 CPPDOM),因此我可以根据需要管理任何内容,因此正确分配和解除分配字符串不会成为问题。

由于我的代码是针对 CPPDOM 的,我认为它对您没有多大用处,但如果您愿意,我可以发布它。

顺便说一句,如果您已经有太多已经使用 RapidXML 的代码,您可以在包装类中重现它的接口。我没有这样做,因为使用 Xerces 的代码没有那么长,而且无论如何我都必须重写它。

于 2010-04-23T01:07:11.260 回答