TinyXML2是C++下解析XML的库,使用比较方便。
从GitHub的TinyXML2页面上下载项目,然后将其中的tinyxml2.cpp
、tinyxml2.h
包含在自己的项目中,就可以使用了,十分简单。
1.解析XML
下面是解析XML的示例代码。
#include<iostream>
#include"tinyxml2.h"
using namespace std;
using namespace tinyxml2;
int main()
{
//输入XML文件路径
char * xml_path = "E:\\satellite_slam_data\\tianjin\\VBZ1_201801051905_002.att";
//新建一个XMLDocument对象
XMLDocument docXml;
//调用对象的LoadFile函数加载文件,并将结果返回给errXML
XMLError errXml = docXml.LoadFile(xml_path);
//如果装载成功
if (XML_SUCCESS == errXml)
{
//获取XML的root节点
XMLElement* elmtRoot = docXml.RootElement();
//获取root节点下第一个名为“AttitudeParameter”的子节点
XMLElement *elmtAttParam = elmtRoot->FirstChildElement("AttitudeParameter");
//新建节点用于获取AttData
XMLElement *elmtAttData = NULL;
//循环获取多个AttData的数据,注意这里循环条件的写法
for (elmtAttData = elmtAttParam->FirstChildElement(); elmtAttData != NULL; elmtAttData = elmtAttData->NextSiblingElement())
{
//TinyXML可以根据节点名称找到节点,也可以按顺序依次读取节点
//例如下面两种写法都可以读取节点内容,但很明显第二种要更灵活一些
//因为第一种是按照顺序读取内容的,一旦标签的顺序变了,那么读取的内容就乱了
//但是第二种是按照节点名称查找的,不需要考虑顺序问题
//因此在实际中应尽量使用第二种方法,这里把第一种方法注释掉了
//第一种,按顺序读取节点
/*XMLElement* AttType = elmtAttData->FirstChildElement();
XMLElement* AttTime = AttType->NextSiblingElement();
XMLElement* UTC = AttTime->NextSiblingElement();
XMLElement* Q0 = UTC->NextSiblingElement();
XMLElement* Q1 = Q0->NextSiblingElement();
XMLElement* Q2 = Q1->NextSiblingElement();
XMLElement* Q3 = Q2->NextSiblingElement();
XMLElement* Roll = Q3->NextSiblingElement();
XMLElement* Pitch = Roll->NextSiblingElement();
XMLElement* Yaw = Pitch->NextSiblingElement();*/
//第二种,按名称读取节点
XMLElement* AttType2 = elmtAttData->FirstChildElement("AttType");
XMLElement* AttTime2 = elmtAttData->FirstChildElement("AttTime");
XMLElement* UTC2 = elmtAttData->FirstChildElement("UTC");
XMLElement* Q02 = elmtAttData->FirstChildElement("Q0");
XMLElement* Q12 = elmtAttData->FirstChildElement("Q1");
XMLElement* Q22 = elmtAttData->FirstChildElement("Q2");
XMLElement* Q32 = elmtAttData->FirstChildElement("Q3");
XMLElement* Roll2 = elmtAttData->FirstChildElement("Roll");
XMLElement* Pitch2 = elmtAttData->FirstChildElement("Pitch");
XMLElement* Yaw2 = elmtAttData->FirstChildElement("Yaw");
}
cout << "Finished." << endl;
}
else
{
cout << "Error open file." << endl;
}
system("pause");
return 0;
}
上述代码读取的对应的部分XML文件如下。 因此上述代码便是对应XML的结构来写的。简单对代码中用到的函数做一些记录和说明。
利用TinyXML2解析文件,第一步是新建一个XMLDocument
对象,然后调用对象的loadFile()
函数加载文件内容。
该函数返回一个XMLError
类型的变量,如果成功XMLError
为0(XML_SUCCESS
),否则是对应的ErrorID
。
然后后面就依次获取根节点等等读取即可。
RootElement()
:用于返回XML文件的根节点。
FirstChildElement()
:这个函数的用途很明确,就是返回第一个子节点。如果没有参数,则返回第一个子节点。如果有参数,则返回以该参数为名的第一个子节点。
注意调用XMLElement中的函数时不是用.
,而是用->
。
NextSiblingElement()
:用于返回和当前节点同级的下一个节点。如上面XML中的AttData节点,即可使用这个函数来遍历。
2.创建XML
通过学习组内的相关代码发现,其实对于创建XML这一块的需求并不是很复杂,所以一般的做法是直接利用输出流自己拼接生成XML了。 当然利用TinyXML2自然也是可以实现的。
#include<iostream>
#include"tinyxml2.h"
using namespace std;
using namespace tinyxml2;
int main()
{
const char* xmlPath = "E:\\test.xml";
const char* declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
XMLDocument doc;
doc.Parse(declaration);
XMLElement* root = doc.NewElement("ROOT");
doc.InsertEndChild(root);
XMLElement* userNode = doc.NewElement("User");
userNode->SetAttribute("Name", "zxh");
userNode->SetAttribute("Age ", "24");
root->InsertEndChild(userNode);
XMLElement* gender = doc.NewElement("Gender");
XMLText* genderText = doc.NewText("Male");
gender->InsertEndChild(genderText);
userNode->InsertEndChild(gender);
XMLElement* mobile = doc.NewElement("Mobile");
mobile->InsertEndChild(doc.NewText("123456"));
userNode->InsertEndChild(mobile);
XMLElement* email = doc.NewElement("Email");
email->InsertEndChild(doc.NewText("zhao@qq.com"));
userNode->InsertEndChild(email);
doc.SaveFile(xmlPath);
return 0;
}
上述代码利用TinyXML2实现了XML的创建,效果如下。
本文作者原创,未经许可不得转载,谢谢配合