概述
C++解析XML, TINYXML2的使用
学习使用tinyxml2,参考https://www.cnblogs.com/happykoukou/p/6307257.html,以及官方tinyxml2的test。
主要知识:
XMLDocument doc;//创建一个dom对象
doc.LoadFile();
doc.Parse(); //将字符串转为dom对象
auto key = doc.NewElement(const char* keyName);//创建一个key
doc.NewText(const char*);//创建一个value
InsertEndChild(key)
FirstChildElement(const char*);
GetText();
SetText(const char*);
NextSiblingElement();//兄弟节点
country.hpp
#pragma once
//删除指针
#define SAFE_DELETE(pRet) if(pRet != NULL) {delete pRet;pRet = NULL;}
//检查xml中的键是否存在,xml的结构已知,若不存在,直接退出
#define KEY_IS_NULL(key) if(key == nullptr){printf("%s is not foundn",#key);exit(-1);}
//为了简单化,以下几个类全部成员函数为public
class Province;
class City;
class City
{
public:
std::string name;
City(const std::string &name):name(name){}
};
class Province
{
public:
std::string name;
std::vector<City> vCities;
Province(const std::string &name):name(name){}
Province(){}
};
class Country
{
public:
std::string name;
std::vector<Province> vProvinces;
public:
Country(const std::string &name):name(name){}
Country(){}
/**
* 将本类的成员变量序列化到一个固定格式的xml文件中
* 采用模板,可以不需要写 tinyxml2的头文件
*/
template<typename T>
int parseXML(T &doc, const std::string &fileName)
{
//xml头
//R"(string)", string可以以原来的形式存在,“” 不需要转义符
const char *declaration = R"(<?xml version="1.0" encoding="UTF-8"?>)";
//将字符串解析到dom对象中
doc.Parse(declaration);
//new 一个 key
//序列化std::string name;
auto roof = doc.NewElement("country");
auto keyCountryName = doc.NewElement("name");
//插入value
keyCountryName->InsertEndChild(doc.NewText(name.c_str()));
//插入</>
roof->InsertEndChild(keyCountryName);
doc.InsertEndChild(roof);
//序列化std::vector<Province> vProvinces;
for(auto province : vProvinces)
{
auto keyProvince = doc.NewElement("province");
roof->InsertEndChild(keyProvince);
auto keyProvinceName = doc.NewElement("name");
keyProvinceName->InsertEndChild(doc.NewText(province.name.c_str()));
keyProvince->InsertEndChild(keyProvinceName);
auto keyCities = doc.NewElement("cities");
keyProvince->InsertEndChild(keyCities);
//序列化std::vector<City> vCities;
for(auto city : province.vCities)
{
auto keyCity = doc.NewElement("city");
keyCity->InsertEndChild(doc.NewText(city.name.c_str()));
keyCities->InsertEndChild(keyCity);
}
}
//保存为xml文件
return doc.SaveFile(fileName.c_str());
}
//反序列化xml文件成一个对象
template<typename T>
int convertXMLToObject(T &doc, const std::string &fileName)
{
int ret = doc.LoadFile(fileName.c_str());
if(ret)
{
return ret;
}
//查找key,如果不存在,则退出程序。
auto keyCountry = doc.FirstChildElement("country");
KEY_IS_NULL(keyCountry);
auto keyCountryName = keyCountry->FirstChildElement("name");
KEY_IS_NULL(keyCountryName);
auto countryName = keyCountryName->GetText();
if(countryName == nullptr)
{
return -1;
}
this->name = countryName;
auto keyProvince = keyCountry->FirstChildElement("province");
//反序列化std::vector<Province> vProvinces;
while(keyProvince != nullptr)
{
auto keyProvinceName = keyProvince->FirstChildElement("name");
KEY_IS_NULL(keyProvinceName);
auto provinceName = keyProvinceName->GetText();
if(provinceName != nullptr)
{
Province province(provinceName);
auto keyCities = keyProvince->FirstChildElement("cities");
KEY_IS_NULL(keyCities);
auto keyCity = keyCities->FirstChildElement("city");
KEY_IS_NULL(keyCity);
//反序列化std::vector<City> vCities;
while(keyCity != nullptr)
{
auto cityName = keyCity->GetText();
if(cityName != nullptr)
{
City city(cityName);
province.vCities.push_back(city);
}
//继续查找兄弟节点
keyCity = keyCity->NextSiblingElement();
}
this->vProvinces.push_back(province);
}
//继续查找兄弟节点
keyProvince = keyProvince->NextSiblingElement();
}
return 0;
}
//序列化对象到string
std::string toString()
{
std::string s;
if(!name.empty())
{
s+= "country name: ";
s+= name;
}
if(!vProvinces.empty())
{
for(auto province : vProvinces)
{
s+= " province name :";
s+= province.name;
if(!province.vCities.empty())
{
s+= " city name: ";
for(auto city : province.vCities)
{
s+= city.name;
s+= " ";
}
}
}
}
return s;
}
};
test.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
#include "../tinyxml2.h"
#include "country.hpp"
using namespace tinyxml2;
using namespace std;
#define EXIT_ABNOEMAL(msg) {printf("%sn", msg); return -1;}
//构造一个country
Country* getCountry(const string &name)
{
auto country = new Country(name);
City haerbing("哈尔滨");
City daqing("大庆");
Province heilongjing("黑龙江");
heilongjing.vCities.push_back(haerbing);
heilongjing.vCities.push_back(daqing);
City guangzhou("广州");
City shenzhen("深圳");
City zhuhai("珠海");
Province guangdong("广东");
guangdong.vCities.push_back(guangzhou);
guangdong.vCities.push_back(shenzhen);
guangdong.vCities.push_back(zhuhai);
City taibei("台北");
City gaoxiong("高雄");
Province taiwan("台湾");
taiwan.vCities.push_back(gaoxiong);
taiwan.vCities.push_back(taibei);
City wulumuqi("乌鲁木齐");
Province xinjiang("新疆");
xinjiang.vCities.push_back(wulumuqi);
country->vProvinces.push_back(xinjiang);
country->vProvinces.push_back(heilongjing);
country->vProvinces.push_back(guangdong);
country->vProvinces.push_back(taiwan);
return country;
}
//序列化对象到xml
int parseCountryToXml(Country *country, const string &filePath)
{
XMLDocument doc;
//调用country的序列化函数
int ret = country->parseXML(doc, filePath);
return ret;
}
//反序列化到对象
int readXMLToCountry(Country * country, const string &filePath)
{
XMLDocument doc;
//调用对象的反序列花方法
int ret = country->convertXMLToObject(doc, filePath);
return ret;
}
int main()
{
const string fileName = "../test/country.xml";
//将中国对象保存到xml中
auto zhongguo = getCountry("zhongguo");
int ret;
ret = parseCountryToXml(zhongguo, fileName);
if(ret)
{
EXIT_ABNOEMAL("convert to xml error!");
}
//从上面的xml中反序列化成china对象
Country *china = new Country();
ret = readXMLToCountry(china, fileName);
if(ret)
{
EXIT_ABNOEMAL("convert to Object error!");
}
//输出china对象
string s = china->toString();
cout<<s<<"n";
//安全删除指针
SAFE_DELETE(zhongguo);
SAFE_DELETE(china);
return 0;
}
结果:
country.xml
<?xml version="1.0" encoding="UTF-8"?>
<country>
<name>zhongguo</name>
<province>
<name>新疆</name>
<cities>
<city>乌鲁木齐</city>
</cities>
</province>
<province>
<name>黑龙江</name>
<cities>
<city>哈尔滨</city>
<city>大庆</city>
</cities>
</province>
<province>
<name>广东</name>
<cities>
<city>广州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>台湾</name>
<cities>
<city>高雄</city>
<city>台北</city>
</cities>
</province>
</country>
最后
以上就是难过酸奶为你收集整理的C++解析XML, TINYXML2的使用C++解析XML, TINYXML2的使用的全部内容,希望文章能够帮你解决C++解析XML, TINYXML2的使用C++解析XML, TINYXML2的使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复