TinyXML2解析、创建XML文件

Apr 1,2018   3762 words   14 min

Tags: C/C++

TinyXML2是C++下解析XML的库,使用比较方便。 从GitHub的TinyXML2页面上下载项目,然后将其中的tinyxml2.cpptinyxml2.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的创建,效果如下。

本文作者原创,未经许可不得转载,谢谢配合

返回顶部