1

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

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

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

4

3 回答 3

4

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

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

不,SAX 解析器不会在这里帮助您。它允许您流式读取(尽管我建议使用拉式解析器而不是推式解析器),但这不允许您将数据插入文件中。我所知道的大多数 XML 解析器通常不支持这一点。他们可以写入数据,但写入和非破坏性插入是两件不同的事情。

于 2012-02-28T15:42:27.070 回答
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);

改变东西。

很抱歉解释得太仓促了,但您需要通读一下文档才能掌握它。

干杯

于 2012-03-07T08:47:32.533 回答
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()以仅检查您需要更改的部分。

于 2012-02-28T16:35:33.897 回答