我正在开发一个项目,该项目需要我将 XML 文件中的一些数据加载到 GUI 上。GUI 允许用户对数据进行一些更改。我想要做的是将这些更改保存回 XML 文件。
我知道可以重写整个文件,但是该文件非常大,并且并非文件中的所有数据都被更改甚至在我的程序中使用。
这是我第一个使用 TinyXML 和 C++ Builder 的项目。我只是在寻找一些关于我应该如何处理这个问题的建议。
我正在开发一个项目,该项目需要我将 XML 文件中的一些数据加载到 GUI 上。GUI 允许用户对数据进行一些更改。我想要做的是将这些更改保存回 XML 文件。
我知道可以重写整个文件,但是该文件非常大,并且并非文件中的所有数据都被更改甚至在我的程序中使用。
这是我第一个使用 TinyXML 和 C++ Builder 的项目。我只是在寻找一些关于我应该如何处理这个问题的建议。
除非您确定新文本的大小与旧文本完全相同,否则仅重写文本文件的一部分通常不是一个好主意。有些文件格式可以进行零碎替换。XML 不是其中之一。至少在一般情况下不是这样。
在文件中间插入数据,从而将其余部分向下移动,基本上相当于加载文件的其余部分,使文件变大,然后将其写回。因此,您也可以加载整个文件,进行修改,然后再次保存。您的代码会更简单,并且可能不会慢很多。
不,SAX 解析器不会在这里帮助您。它允许您流式读取(尽管我建议使用拉式解析器而不是推式解析器),但这不允许您将数据插入文件中。我所知道的大多数 XML 解析器通常不支持这一点。他们可以写入数据,但写入和非破坏性插入是两件不同的事情。
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);
改变东西。
很抱歉解释得太仓促了,但您需要通读一下文档才能掌握它。
干杯
正如我在评论中所说,我认为插入文件中间不会更好。但是,如果您需要/想要额外的安全性,我建议您执行两个额外的步骤:
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()
以仅检查您需要更改的部分。