代码之家  ›  专栏  ›  技术社区  ›  Roddy

如何解决RapidXML字符串所有权问题?

  •  7
  • Roddy  · 技术社区  · 14 年前

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

    对我来说最糟糕的是:

    3.2字符串的所有权。

    RapidXML生成的节点和属性不 拥有自己的名称和值字符串。他们 只需抓住指向它们的指针。这个 意味着你必须小心 通过手动设置这些值 使用 xml_base::name(const Ch *) xml_base::value(const Ch *) 功能。

    必须注意确保 传递的字符串的生存期为 至少只要生命的 节点/属性。最简单的方法 实现它是分配字符串 从内存池 文件。使用 memory_pool::allocate_string() 为此目的发挥作用。

    现在,我知道这是为了速度而做的,但这感觉就像是一场等待发生的车祸。下面的代码看起来无害,但是当foo返回时,“name”和“value”超出范围,所以文档是未定义的。

    void foo()
    {
      char name[]="Name";
      char value[]="Value";
    
      doc.append_node(doc.allocate_node(node_element, name, value));
    }
    

    使用建议 allocate_string() 按手工操作,但很容易忘记。

    是否有任何“增强的”RapidXML来避免这个问题?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Fabio Ceconello    14 年前

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

    我开始使用Xerces,但我发现它很重,除了其他一些小麻烦之外,所以我搬到了CPP。当我进行这一操作时,我决定创建一组包装类,这样我的代码就不会依赖于特定的XML“引擎”,如果需要,我可以移植到另一个。

    我创建了自己的类来表示基本的DOM实体(节点、文档等)。这些类在内部使用pimpl习语来使用cppdom对象。 因为我的node对象包含“real”节点对象(来自cppdom),所以我可以根据需要管理任何东西,所以字符串的正确分配和释放不会有问题。

    因为我的代码是用于CPPDOM的,所以我认为它对您不太有用,但如果您需要,我可以发布它。

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