2014-01-07 30 views
0

我过去曾经用过RapidXML,很少有的问题,但是这个问题让我难堪。RapidXML属性值错误

我正在创建应用程序事件时间戳的日志,外部程序可以在正确的时间重播原始应用程序中的任何音频。

在应用程序的初始化,下面的XML正确生成:

<?xml version="1.0" encoding="utf-8"?> 
<playbacklog> 
    <logitem type="general" event="start" timestamp="85639323"/> 
</playbacklog> 

一旦下一个项目将被添加,该文件就变成了这样:

<?xml version="1.0" encoding="utf-8"?> 
<playbacklog> 
    <logitem type="general" event="start" timestamp="NUL NUL NUL NUL"/> 
    <logitem type="audio" event="start" timestamp="86473833"> 
</playbacklog> 

然后:

<?xml version="1.0" encoding="utf-8"?> 
<playbacklog> 
    <logitem type="general" event="start" timestamp="@NUL NUL' NUL NUL"/> 
    <logitem type="audio" event="start" timestamp="NUL NUL NUL NUL"> 
    <logitem type="audio" event="stop" timestamp="8654533"> 
</playbacklog> 

随着每个新增的开始停止对,最终以下行为还可以看出,与时间戳值被改变为都具有相同的事件的节点的属性值:

<?xml version="1.0" encoding="utf-8"?> 
<playbacklog> 
    <logitem type="general" event="start" timestamp="@NUL NUL' NUL NUL"/> 
    <logitem type="audio" event="start" timestamp="NUL NUL NUL NUL"> 
    <logitem type="audio" event="stop" timestamp="8674519"> 
    <logitem type="audio" event="start" timestamp="NUL NUL NUL NUL"> 
    <logitem type="audio" event="stop" timestamp="8674519"> 
    <logitem type="audio" event="start" timestamp="NUL NUL NUL NUL"> 
    <logitem type="audio" event="stop" timestamp="8674519"> 
</playbacklog> 

我声明该文档作为这样在C++头文件:

private: 
    rapidxml::xml_document<> outputDocument; 

为了创建每个节点,我使用下面的代码:

// tStamp is a typedef'd std::pair containing two std::string values, one for the 
// time at which the evet occurred and the other containing the event type. 
void AudioLogger::LogEvent(Timestamp* tStamp) 
{ 
    rapidxml::xml_node<>* nodeToAdd = outputDocument.allocate_node(rapidxml::node_element, "logitem"); 
    ... 
    nodeToAdd->append_attirbute(outputDocument.allocate_attribute("timestamp", ts->first.c_str())); 
    ... 

    outputDocument.first_node()->next_sibling()->append_node(nodeToAdd); 
} 

时间戳*传递给这个函数的值被保存在一个std :: vector中,当添加一个新函数时,这个函数被调用。

如果有人对这里发生的事情有任何想法,这将是一个巨大的帮助。另外,如果需要更多信息,我也可以提供。

回答

1

这是一个经典的RapidXML'gotcha'。无论何时将字符指针传递给RapidXML,它只是存储指针而不是制作字符串的副本。它有明确的记录,但仍频繁地将人们赶出去。 http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1modifying_dom_tree

答案是使用allocate_string功能是这样的:

nodeToAdd->append_attribute(outputDocument.allocate_attribute("timestamp", 
          outputDocument.allocate_string(ts->first.c_str()))); 

(你不需要在allocate_string包“时间戳”,因为这是一个文字等不会改变)。

我通常用我自己的助手的包装 - 是这样的: -

class MyRapidXmlDoc : public rapidxml::xml_document<char> 
{ 
... 
    Attribute* allocateAttribute(const string &name, const string &value = "") 
    { 
    if (value.empty()) 
     return allocate_attribute(allocate_string(name.c_str())); 
    else 
     return allocate_attribute(allocate_string(name.c_str()), allocate_string(value.c_str())); 
    }