我过去曾使用过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);
}
传递给此函数的TimeStamp *值保存在std :: vector中,当添加新函数时,将调用此函数。
如果有人对这里发生的事情有任何想法,那将是一个巨大的帮助。此外,如果需要更多信息,我也可以提供此信息。
答案 0 :(得分:1)
这是一款经典的RapidXML“gotcha”。每当你将一个char指针传递给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中包含“timestamp”,因为这是一个文字,所以不会改变)。
我通常使用自己的帮助程序包装器 - 如下所示: -
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()));
}