背景交代:
tinyXML用过几次了,但每次找相关文件都很烦,虽然有些地方可以免费下载,还是上传一份这次找到的,防止以后再去找的时候迷路或收费。下载我上传的需要C币或者积分吧,这里给新人一个免费下载的地址吧:
https://sourceforge.net/projects/tinyxml/
我这里并没有使用下载的工程,只是将里边的:tinystr.cpp 、tinystr.h 、tinyxml.cpp 、tinyxml.h 、tinyxmlerror.cpp和tinyxmlparser.cpp这6个文件拿出来放到自己的工程里边了,其他的文件没有去过多研究 。
值得一提的是,可能有些人会困惑为什么网上的TinyXML示例代码基本都是用的指针,因为TinyXML除了创建文件类外,所有创建节点类的析构函数都使用了delete来自动释放内存,所以你在创建新的节点时必须要用指针new一块堆空间,如果你用了栈上的对象就会出现delete了一块未知空间而导致程序崩溃。
如果你定义自己的类时,不想在外面显示的释放内存,就可以学这里把delete放在析构函数中。当涉及到继承时,请不要忘记把析构函数定义为虚函数,不然也会出问题。
OK废话不多说,上一段简单的代码吧
注意:根据自己创建的工程,改变包含的头文件,我这里创建的是空的C++项目,所以头文件中的#include "stdafx.h"都被我注释掉了。
一、生成或打开XML文件,并在文件末尾追加节点
#include "tinyxml.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
TiXmlDocument testDoc;
TiXmlElement* root;
if (testDoc.LoadFile("test.xml"))
{///加载文件成功则赋值根节点
cout << "XML Load Success !" << endl;
root = testDoc.FirstChildElement();
}
else
{///文件不存在,加载失败,创建根节点
cout << "XML Load Failed !" << endl;
root = new TiXmlElement("annotation");
testDoc.LinkEndChild(root);
TiXmlElement* fdr = new TiXmlElement("folder");
TiXmlText* folderText = new TiXmlText("VOC2007");
fdr->LinkEndChild(folderText);
root->LinkEndChild(fdr);
TiXmlElement* fname = new TiXmlElement("filename");
TiXmlText* filename = new TiXmlText("000009.jpg");
fname->LinkEndChild(filename);
root->LinkEndChild(fname);
}
///这里就是在末尾追加节点了,将程序执行两边就可以看出效果了
TiXmlElement* source = new TiXmlElement("source");
root->LinkEndChild(source);
TiXmlElement* sourcedb = new TiXmlElement("database");
TiXmlText* dbText = new TiXmlText("The VOC2007 Database");
sourcedb->LinkEndChild(dbText);
source->LinkEndChild(sourcedb);
TiXmlElement* sourceannotation = new TiXmlElement("annotation");
TiXmlText* sourceann = new TiXmlText("PASCAL VOC2007");
sourceannotation->LinkEndChild(sourceann);
source->LinkEndChild(sourceannotation);
testDoc.SaveFile("Test.xml");
cout << "Main Function Finished, Press Any Key To Exit...." << endl;
system("pause");
return 0;
}
创建的XML文件内容如下:
<annotation>
<folder>VOC2007</folder>
<filename>000009.jpg</filename>
<source>
<database>The VOC2007 Database</database>
<annotation>PASCAL VOC2007</annotation>
</source>
</annotation>
二、查找并修改某个节点内容
//批量修改xml中filename结点内容与文件名不相同的问题
void repairXmlfilename(const char *xmlDir)
{
struct _finddata_t fileInfo;
intptr_t fHandle;
char filePath[256];
char fileName[256];
char jpgName[256];
memset(filePath, 0, sizeof(filePath));
sprintf_s(filePath, "%s/*.xml", xmlDir);
if ((fHandle = _findfirst(filePath, &fileInfo)) == -1L)
{//判断给入路径中是否存在xml文件
cout << "There is any xml file !" << endl;
return;
}
do
{
memset(fileName, 0, sizeof(fileName));
sprintf_s(fileName, "%s/%s", xmlDir, fileInfo.name);
memset(jpgName, 0, sizeof(jpgName));
sprintf_s(jpgName, "%s", fileInfo.name);
int len = strlen(jpgName);
jpgName[len - 3] = 'j';
jpgName[len - 2] = 'p';
jpgName[len - 1] = 'g';
TiXmlDocument xmlDoc;
cout << fileName << endl;
if (xmlDoc.LoadFile(fileName))
{//加载xml文件
TiXmlElement* root = xmlDoc.FirstChildElement();
if (root == NULL)
{//文件内没有节点,加载下一个
cout << "RootElement is NULL ,xml load failed !" << endl;
continue;
}
for (TiXmlElement* childNode = root->FirstChildElement();childNode != NULL;childNode = childNode->NextSiblingElement())
{
string childName = childNode->Value();
if (childName == "filename")
{
TiXmlText* nameText = new TiXmlText(jpgName);
childNode->Clear();
childNode->LinkEndChild(nameText);
break;
}
}
xmlDoc.SaveFile(fileName);
}
else
{
cout << "xml load failed !" << endl;
}
} while (_findnext(fHandle, &fileInfo) == 0);
}
程序功能都很简单,这里就不做解释了,TinyXML还有很多功能,介绍它的也有很多,我这里主要介绍这两点其他的就不再多说了,感兴趣可以去别的地方学习。
最后,如果转载,注明出处,谢谢!