使用RapidXML更新C ++中的XML节点和属性值

时间:2018-10-14 04:09:07

标签: c++ xml persistence rapidxml

我有一个XML文件,该文件用于存储相机参数,这些参数将根据UI的更改而更新。使用RapidXML,我可以读取XML文件,所有元素及其属性值。但是,当我尝试更新attribrute /元素的值并保存时,该文件不会反映新值,而是显示旧值。我试图在像这样的小型XML文件上测试这个概念

<?xml version="1.0" encoding="UTF-8"?>
<note>
    <to>Kum</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Dont forget me this weekend!</body>
</note>

这只是一个没有属性的简单示例文件> 这就是我的代码。

rapidxml::xml_document<> doc;
std::fstream file("TestFile.xml",std::ios::in|std::ios::out);

std::stringstream bufferStream;
bufferStream << file.rdbuf();
std::string content(bufferStream.str());
std::vector<char> buffer(content.begin(), content.end());
buffer.push_back('\0');
doc.parse<rapidxml::parse_no_data_nodes>(&content[0]);

rapidxml::xml_node<>* rootNode = doc.first_node();
std::cout <<"<"<< rootNode->name() <<">" << "\n";
rapidxml::xml_node<>* firstNode = rootNode->first_node("to");
std::cout << "<"<<firstNode->name()<<">" <<firstNode->value()<< "\n";

rapidxml::xml_node<> *real_thing = rootNode->first_node("from");

if (real_thing != nullptr)                              
{
    real_thing->value("yuck");  // now that should work
    std::cout << real_thing->name() << real_thing->value() << "\n";
}

在这里我很困惑。如何将更改保存回原始xml文件。如果我这样做,

file << bufferStream.str();

它不仅不保存新值,而且似乎附加了整个XML DOM而不是替换原始元素值。如果有人可以分享实现该目标的一些摘要,我将不胜感激。 我一整天都在浏览文档,但也不了解传递给parse函数的标志。

谢谢

1 个答案:

答案 0 :(得分:1)

RapidXML使用指向传递给std::vector<char>的{​​{1}}中所保存的文本数据的指针来保持文档结构的内部表示。

当您修改节点的'值时,您实际上只是在更改内部结构中的指针。您需要使用parse中的函数返回字符串,该函数包括用于写入流的运算符。

rapidxml_print.hpp

为什么要追加?因为在读取数据之后,流的位置在文件的末尾。您可以使用file << doc; 重置为开头,但是如果新数据比旧数据短,则不会截断文件。

最好的方法是简单地将数据写到新的file.seek(0)中,而不是尝试同时打开数据进行读写。

另请参见此处,以更简洁,更快速的方式使用RapidXML解析文件。 How to parse the XML file in RapidXML