如何使用TinyXML保存对XML文件的更改?

时间:2012-02-28 14:46:23

标签: c++ xml-parsing c++builder tinyxml

我正在开发一个项目,要求我将一些XML文件中的数据加载到GUI上。 GUI允许用户对数据进行一些更改。我希望能够做的是将这些更改保存回XML文件。

我知道可以重写整个文件,但文件非常庞大,并且文件中的所有数据都没有被更改,甚至没有在我的程序中使用。

这是我第一个使用TinyXML和C ++ Builder的项目。我只是在寻找一些关于如何处理这个问题的建议。

3 个答案:

答案 0 :(得分:4)

除非您确定新文本的大小与旧文本完全相同,否则只重写文本文件的一部分通常不是一个好主意。有文件格式可以零碎地替换。 XML不是其中之一。不是一般情况下,至少。

在文件中间插入数据,从而将其余部分向下移动,基本上相当于加载文件的其余部分,使文件更大,并将其写回。所以你也可以加载整个文件,进行修改,然后再次保存。你的代码会更简单,也可能不会慢得多。

不,SAX解析器不会在这里帮助你。它允许您流式读取(虽然我建议使用拉解析器而不是推送解析器),但这不允许您将数据插入到文件中。我所知道的大多数XML解析器通常都不支持这种方法。他们可以数据,但写作和非破坏性插入是两回事。

答案 1 :(得分:2)

TinyXml可以让你做你想做的事情,而不会损坏文件内容(只要它的有效xml)。我刚检查过这个,所以我很确定。显然,您必须知道要精确编辑哪些属性和标签,但您可以添加/编辑标签,而不会影响现有属性/标签/注释,即使在您编辑的标签内也是如此。你需要一段时间才能习惯结构,但这绝对是可能的。

你必须知道xml的结构!

TiXmlDocument doc("filepath"); //will open your document

if (!doc.LoadFile()) //you do have to open the whole file
{
    cout<<"No XML structure found"<<endl;
    return; // exit function don't load anything
}
TiXmlElement *root = doc.RootElement(); //pointer to root element

现在您可以使用此指针和命令,如:

root->FirstChild("tageone")->ToElement();
tageone->SetDoubleAttribute("attribute", value);

改变一些东西。

对于匆忙的解释感到抱歉,但是你需要仔细阅读文档才能掌握它。

欢呼声

答案 2 :(得分:0)

更新

正如我在评论中所说,如果你插入文件的中间,我认为你不会更好。但是,如果您需要/想要额外的安全性,我建议另外两个步骤:

  • 在所有重要步骤中对xml文件执行完整性检查。这可以是确保您正在阅读的文件确实是您所需要的任何内容。
  • 在保存之前计算整个文件内容的校验和,然后检查它。这不一定是CRC,我只是命名函数calculate_crc()。任何可以验证数据完整性的东西都是好的。

我会大致如下(伪代码):

TiXmlDocument doc( "demo.xml" );
doc.LoadFile();

perform_sanitycheck(doc);

//  do whatever you need to change

perform_sanitycheck(doc);
unsigned int crc = calculate_crc(doc);

doc.SaveFile("temp_name.xml");  // save the file under another name

TiXmlDocument doc2( "temp_name.xml" );
perform_sanitycheck(doc2);
if(verify_crc(doc, crc))
{
    delete_file("demo.xml");
    rename_file("temp_name.xml", "demo.xml");
}

如有必要,完整性检查将采取适当的措施。您需要将两个函数delete_file()rename_file()替换为您的环境的API或库函数。

可以专门设计函数calculate_crc()verify_crc(),以便仅检查您需要保持不变的部分。