热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++解析XML,TINYXML2的使用

C解析XML,TINYXML2的使用学习使用tinyxml2,参考https:www.cnblogs.comhappykoukoup6307257.html
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 found\n",#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 vCities;Province(const std::string &name):name(name){}Province(){}
};class Country
{
public:std::string name;std::vector vProvinces;public:Country(const std::string &name):name(name){}Country(){}/*** 将本类的成员变量序列化到一个固定格式的xml文件中* 采用模板,可以不需要写 tinyxml2的头文件*/templateint parseXML(T &doc, const std::string &fileName){//xml头//R"(string)", string可以以原来的形式存在,“” 不需要转义符const char *declaration = R"()";//将字符串解析到dom对象中doc.Parse(declaration);//new 一个 key//序列化std::string name;auto roof = doc.NewElement("country");auto keyCountryName = doc.NewElement("name");//插入valuekeyCountryName->InsertEndChild(doc.NewText(name.c_str()));//插入roof->InsertEndChild(keyCountryName);doc.InsertEndChild(roof);//序列化std::vector 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 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文件成一个对象templateint 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 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 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; }//序列化对象到stringstd::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
#include
#include
#include
#include "../tinyxml2.h"#include "country.hpp"using namespace tinyxml2;
using namespace std;#define EXIT_ABNOEMAL(msg) {printf("%s\n", 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 &#61; "../test/country.xml";//将中国对象保存到xml中auto zhongguo &#61; getCountry("zhongguo");int ret;ret &#61; parseCountryToXml(zhongguo, fileName);if(ret){EXIT_ABNOEMAL("convert to xml error!");}//从上面的xml中反序列化成china对象Country *china &#61; new Country();ret &#61; readXMLToCountry(china, fileName);if(ret){EXIT_ABNOEMAL("convert to Object error!");}//输出china对象string s &#61; china->toString();cout<}
结果&#xff1a;country.xml
zhongguo新疆乌鲁木齐黑龙江哈尔滨大庆广东广州深圳珠海台湾高雄台北

 


推荐阅读
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文介绍如何使用 Python 将一个字符串按照指定的行和元素分隔符进行两次拆分,最终将字符串转换为矩阵形式。通过两种不同的方法实现这一功能:一种是使用循环与 split() 方法,另一种是利用列表推导式。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • 探讨如何高效使用FastJSON进行JSON数据解析,特别是从复杂嵌套结构中提取特定字段值的方法。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • Splay Tree 区间操作优化
    本文详细介绍了使用Splay Tree进行区间操作的实现方法,包括插入、删除、修改、翻转和求和等操作。通过这些操作,可以高效地处理动态序列问题,并且代码实现具有一定的挑战性,有助于编程能力的提升。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
author-avatar
来人把老师拖出I去毙了
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有