经常遇到需要读写XML的地方,一般在C++中读写XML都会用到一个C++库tinyXml类库,这个类库可以直接下载,并解压,得到了一种6个源文件,其中4个cpp文件,2个h头文件,在使用中只需要将这个6个文件拷贝到工程目录下,再#include两个h头文件即可,即可在工程中使用这个库进行XML文件的读取了。6个文件如下:
一、C++读取XML文件
以读取如下的XML文件为例:
需要读取的每个object节点下的bndbox的的四个int数据,但是不同的xml的object的个数不一致。
头文件如下:
//打开xml文件需要加载的头文件
#include "tinystr.h"
#include "tinyxml.h"
代码如下:
bool ReadParaXml(string m_strXmlPath, vector<BoxSize>& vecNode)
{
BoxSize *pNode = new BoxSize;
//读取xml文件中的参数值
TiXmlDocument* Document = new TiXmlDocument();
if(!Document->LoadFile(m_strXmlPath.c_str()))
{
cout << "无法加载xml文件!" << endl;
cin.get();
return false;
}
TiXmlElement* RootElement = Document->RootElement(); //根目录
TiXmlElement* NextElement = RootElement->FirstChildElement(); //根目录下的第一个节点层
//for(NextElement;NextElement;NextElement = NextElement->NextSiblingElement())
while(NextElement!=NULL) //判断有没有读完
{
if(NextElement->ValueTStr() == "object") //读到object节点
{
//NextElement = NextElement->NextSiblingElement();
TiXmlElement* BoxElement = NextElement->FirstChildElement();
while(BoxElement->ValueTStr() != "bndbox") //读到box节点
{
BoxElement = BoxElement->NextSiblingElement();
}
//索引到xmin节点
TiXmlElement* xminElemeng = BoxElement->FirstChildElement();
{
//分别读取四个数值
pNode->xMin = atof(xminElemeng->GetText());
TiXmlElement* yminElemeng = xminElemeng->NextSiblingElement();
pNode->yMin = atof(yminElemeng->GetText());
TiXmlElement* xmaxElemeng = yminElemeng->NextSiblingElement();
pNode->xMax = atof(xmaxElemeng->GetText());
TiXmlElement* ymaxElemeng = xmaxElemeng->NextSiblingElement();
pNode->yMax = atof(ymaxElemeng->GetText());
//加入到向量中
vecNode.push_back(*pNode);
}
}
NextElement = NextElement->NextSiblingElement();
}
//释放内存
delete pNode;
delete Document;
cout << "完成xml的读取" << endl;
return true;
}
其中boxsize结构体的定义如下:
//box参数结构体
struct BoxSize
{
int xMin;
int yMin;
int xMax;
int yMax;
};
几个函数语句:
Document->RootElement();
作用:读取xml的根节点
TiXmlElement* NextElement = RootElement->FirstChildElement();
作用:读取xml根节点下一层的第一个节点。FirstChildElemnt()获取当前节点的下一层的第一个节点。比如,如果读到了object节点,再使用该函数就读到了name节点。
NextElement = NextElement->NextSiblingElement()
作用:NextSiblingElement()读取当前节点这一层的下一个节点(注意是当前这一层)。比如,如果读到了Source节点,再使用该函数就读到了owner节点,但是如果使用FirstChildElemnt()就读到了该Source节点下一层的第一个节点database节点。
BoxElement->ValueTStr()
作用:获取当前节点的名字,这样可以判断现在是都读到了我想要读的节点,比如读到了Source节点,返回是就是字符串“Source”。
xminElemeng->GetText()
作用:获取当前节点中的数据值。比如读到了Xmin节点,就返回了节点中的这个int的数据值。
最后如果读完了这一层的所有的节点,指针将为NULL。因此可以用来判断该节点所在层的节点有没有读完。