QT开发技术 【基于TinyXml2的对类进行序列化和反序列化】一

一、对TinyXml2 进行封装 使用宏 实现序列化和反序列化

思路:
利用宏增加一个类函数,使用序列化器调用函数进行序列化

封装宏示例

#define XML_SERIALIZER_BEGIN(ClassName) \
public: \virtual void ToXml(XMLElement* parentElem, bool bSerialize = true) { \if (bSerialize) { \parentElem->SetName(#ClassName); \}\
#define XML_SERIALIZER_VAR(Name, Value) \if (bSerialize) { \CXmlImplement::WriteElement(parentElem, Name, Value); \} \else { \CXmlImplement::ReadElement(parentElem, Name, Value); \} \

#define XML_SERIALIZER_STL_VAR(Name, Value) \if (bSerialize) { \CXmlImplement::WriteSTLElement(parentElem, Name, Value); \} \else { \CXmlImplement::ReadSTLElement(parentElem, Name, Value); \} \

#define XML_SERIALIZER_ARRAY(Name, Object) \if (bSerialize) { \CXmlImplement::WriteElementObject(parentElem, Name, Object); \} \else { \CXmlImplement::ReadElementObject(parentElem, Name, Object); \} \

#define XML_SERIALIZER_END() \} \

目前只封装了简单使用的,需要其他自己可以增加

二、类使用宏

新建一个student 类 增加宏

class CStudent
{
public:CStudent(){std::cout << "Constructor CStudent" << std::endl;}~CStudent(){std::cout << "Destructor CStudent" << std::endl;}XML_SERIALIZER_BEGIN(CStudent)XML_SERIALIZER_VAR("学号", m_nStudentID)XML_SERIALIZER_VAR("姓名", m_strName)XML_SERIALIZER_VAR("年龄", m_nAge)XML_SERIALIZER_VAR("性别", m_nSex)XML_SERIALIZER_END()int m_nStudentID;std::string m_strName;int m_nAge;int m_nSex;
};  

这样一个类就增加了想要的序列化函数

三、实现序列化器

利用TinyXml2实现序列化器封装

3.1、TinyXml2介绍

TinyXML-2 是一个简单,小型,高效的 C ++ XML 解析器,可以轻松集成到其他程序中,直接引用源文件的话只需要包含两个文件(h 和 cpp,此外还有个测试文件里面带有 demo)。TinyXML-2 解析 XML 文档,并以此为基础构建可读取,修改和保存的文档对象模型(DOM)。文档说,在解释 XML 时仅使用 UTF-8 ,假定所有 XML 为 UTF-8 (看了下使用 MSVC 编译器时生成的 XML 文件文本编码使用的本地编码)。该库还支持打印到文件或内存,使用 XMLPrinter 类。GitHub 链接:[链接](https://github.com/leethomason/tinyxml2)

使用模板对TinyXml2 序列化进行封装

/*
**  File name:   XmlImplement.h
**  Author:      
**  Date:        2025-01-16
**  Brief:       xml序列化实现类
**  Copyright (C) 1392019713@qq.com All rights reserved.
*/#pragma once
#include <string>
#include <vector>
#include <iostream>
#include "tinyxml2.h"
#include "XmlSerializerExportLib.h"using namespace tinyxml2;class  CXmlImplement {
public:template <typename T>static void WriteElement(XMLElement* parentElem, const std::string& elementName, const T& value) {XMLElement* elem = parentElem->GetDocument()->NewElement(elementName.c_str());elem->SetText(value);parentElem->InsertEndChild(elem);}static void WriteElement(XMLElement* parentElem, const std::string& elementName, const std::string& value) {XMLElement* elem = parentElem->GetDocument()->NewElement(elementName.c_str());elem->SetText(value.c_str());parentElem->InsertEndChild(elem);}template <typename T>static void WriteSTLElement(XMLElement* parentElem, const std::string& elementName, const std::vector<T>& values) {XMLElement* vectorElem = parentElem->GetDocument()->NewElement(elementName.c_str());if (!vectorElem){return;}for (const auto& value : values) {WriteElement(vectorElem, elementName + "Item", value);}parentElem->InsertEndChild(vectorElem);}template <typename T>static void ReadElement(XMLElement* parentElem, const std::string& elementName, T& value) {XMLElement* elem = parentElem->FirstChildElement(elementName.c_str());if (elem) {value = std::stoi(elem->GetText());}}static void ReadElement(XMLElement* parentElem, const std::string& elementName, std::string& value) {XMLElement* elem = parentElem->FirstChildElement(elementName.c_str());if (elem) {value = elem->GetText();}}template <typename T>static void ReadSTLElement(XMLElement* parentElem, const std::string& elementName, std::vector<T>& values) {XMLElement* vectorElem = parentElem->FirstChildElement(elementName.c_str());if (!vectorElem){return;}for (XMLElement* elem = vectorElem->FirstChildElement(); elem; elem = elem->NextSiblingElement()){T value;ReadElement(elem, elem->Name(), value);values.push_back(value);}}template <typename T>static void WriteElementObject(XMLElement* parentElem, const std::string& elementName,  T* pT) {XMLElement* elem = parentElem->GetDocument()->NewElement(elementName.c_str());pT->ToXml(elem);parentElem->InsertEndChild(elem);}template <typename T>static void WriteElementObject(XMLElement* parentElem, const std::string& elementName, const std::vector<T*>& objects) {XMLElement* vectorElem = parentElem->GetDocument()->NewElement(elementName.c_str());for (const auto& object : objects) {WriteElementObject(vectorElem, elementName + "Item", object);}parentElem->InsertEndChild(vectorElem);}template <typename T>static void ReadElementObject(XMLElement* parentElem, const std::string& elementName, T* pT, bool array = false) {XMLElement* elem;if (array){elem = parentElem;}else{elem = parentElem->FirstChildElement(elementName.c_str());}if (elem) {pT->ToXml(elem, false);}}template <typename T>static void ReadElementObject(XMLElement* parentElem, const std::string& elementName, std::vector<T*>& vecObjs) {XMLElement* objectElem = parentElem->FirstChildElement(elementName.c_str());for (XMLElement* elem = objectElem->FirstChildElement(); elem; elem = elem->NextSiblingElement()){T* pT = new T();ReadElementObject(elem, elem->Name(), pT, true);vecObjs.push_back(pT);}}template <typename T>static bool Serialize(std::string& strXml, T* pT) {bool bRet = false;if (!pT){return bRet;}XMLDocument doc;XMLDeclaration* declaration = doc.NewDeclaration();declaration->SetValue("xml version=\"1.0\" encoding=\"GB2312\"");doc.InsertFirstChild(declaration);XMLElement* rootElem = doc.NewElement("Root");if (!rootElem){return bRet;}pT->ToXml(rootElem);doc.InsertEndChild(rootElem);XMLPrinter printer;doc.Accept(&printer);strXml = printer.CStr();return true;}template <typename T>static bool Deserialize(const std::string& xml, T* pT) {bool bRet = false;if (!pT){return bRet;}XMLDocument doc;XMLError result = doc.Parse(xml.c_str());if (result != XML_SUCCESS) {std::cerr << "Failed to parse XML: " << XMLDocument::ErrorIDToName(result) << std::endl;return bRet;}XMLElement* rootElem = doc.RootElement();if (rootElem) {pT->ToXml(rootElem, false);}return true;}
};

四、使用测试

增加2个类测试

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include "../../XmlSerialize/Include/XmlSerializer.h"class CStudent
{
public:CStudent(){std::cout << "Constructor CStudent" << std::endl;}~CStudent(){std::cout << "Destructor CStudent" << std::endl;}XML_SERIALIZER_BEGIN(CStudent)XML_SERIALIZER_VAR("学号", m_nStudentID)XML_SERIALIZER_VAR("姓名", m_strName)XML_SERIALIZER_VAR("年龄", m_nAge)XML_SERIALIZER_VAR("性别", m_nSex)XML_SERIALIZER_END()int m_nStudentID;std::string m_strName;int m_nAge;int m_nSex;
};  class CClass //: public CXmlSerializer
{
public:CClass(){}~CClass(){for (auto itr = m_vecStudents.begin(); itr != m_vecStudents.end();){CStudent* pStudent = *itr;if (pStudent){std::cout << pStudent->m_nStudentID << " " << pStudent->m_strName << std::endl;delete pStudent;itr = m_vecStudents.erase(itr);}else{++itr;}}m_vecStudents.clear();}XML_SERIALIZER_BEGIN(CClass)XML_SERIALIZER_VAR("班级名称", m_strName)XML_SERIALIZER_VAR("班级ID", m_nClassID)XML_SERIALIZER_ARRAY("学生列表", m_vecStudents)XML_SERIALIZER_END()std::string m_strName;int m_nClassID;std::vector<CStudent*> m_vecStudents;
};void TestXml()
{{CStudent student;student.m_nStudentID = 1001;student.m_strName = "张三";student.m_nAge = 20;student.m_nSex = 1;std::string strXml;CXmlImplement::Serialize(strXml, &student);std::ofstream ofs("E:/Project/Inlib/Base/Examples/Bin/Debug/student.xml");ofs << strXml;CStudent student2;CXmlImplement::Deserialize(strXml, &student2);std::cout << student2.m_nStudentID << std::endl;std::cout << student2.m_strName << std::endl;student2.m_strName = "李四";student2.m_nStudentID = 1002;CClass class1;class1.m_strName = "1班";class1.m_nClassID = 101;class1.m_vecStudents.push_back(&student);class1.m_vecStudents.push_back(&student2);CXmlImplement::Serialize(strXml, &class1);std::ofstream ofs1("E:/Project/Inlib/Base/Examples/Bin/Debug/class.xml");ofs1 << strXml;}std::cout << "------class Begin--------------" << std::endl;std::ifstream ifs("E:/Project/Inlib/Base/Examples/Bin/Debug/class.xml");std::string strXml = std::string((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());CClass class2;CXmlImplement::Deserialize(strXml, &class2);std::cout << class2.m_strName << std::endl;
}int main()
{TestXml();return 0;
}

生成结果

在这里插入图片描述

如果文章帮到你,动动小手点赞 (-_-)

下一篇文章链接 QT开发技术 【基于TinyXml2的对类进行序列化和反序列化】 二

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/3551.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++速览之智能指针

1、存在的问题 c 把内存的控制权对程序员开放&#xff0c;让程序显式的控制内存&#xff0c;这样能够快速的定位到占用的内存&#xff0c;完成释放的工作。但是此举经常会引发一些问题&#xff0c;比如忘记释放内存。由于内存没有得到及时的回收、重复利用&#xff0c;所以在一…

【Pytorch实用教程】TCN(Temporal Convolutional Network,时序卷积网络)简介

文章目录 TCN的基本特点TCN的优点TCN的应用场景典型的TCN架构总结TCN(Temporal Convolutional Network,时序卷积网络)是一种用于处理序列数据的深度学习模型,尤其适用于时间序列预测、语音识别、自然语言处理等任务。它利用卷积神经网络(CNN)来处理时序数据,相比于传统的…

对话 TDengine 解决方案中心总经理陈肃:构建技术与市场的桥梁

TD 小T导读 他是大数据领域的杰出专家&#xff0c;拥有超过十项一作发明专利&#xff0c;是中国通信行业标准《大数据 消息中间件技术要求与测试方法》的重要编写者&#xff0c;并凭借数据中间件领域的突出成就荣获 2019 年“CJK OSS Award”。他是腾讯云 TVP 专家和 TGO 鲲鹏会…

【PCL】Segmentation 模块—— 欧几里得聚类提取(Euclidean Cluster Extraction)

1、简介 PCL 的 Euclidean Cluster Extraction&#xff08;欧几里得聚类提取&#xff09; 是一种基于欧几里得距离的点云聚类算法。它的目标是将点云数据分割成多个独立的簇&#xff08;clusters&#xff09;&#xff0c;每个簇代表一个独立的物体或结构。该算法通过计算点与点…

动态主机配置协议 (DHCPv4)介绍,详细DHCP协议学习笔记

定义 动态主机配置协议 (DHCP) 是一种用于集中对用户 IPv4 地址进行动态管理和配置的技术。为与 IPv6 动态主机配置协议 (DHCPv6) 进行区分&#xff0c;本文统一将动态主机配置协议称为 DHCPv4。 DHCPv4 协议由 RFC 2131 定义&#xff0c;采用客户端/服务器通信模式&#xff…

玩转大语言模型——使用graphRAG+Ollama构建知识图谱

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型——使用graphRAGOllama构建知识图谱 文章目录 系列文章目录前言下载和安装用下载项目的方式下载并安装用pip方式下载并安装 生成知…

Nginx三种不同类型的虚拟主机(基于域名、IP 和端口)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年1月15日13点14分 目录 1. 基于域名的虚拟主机 …

pytest-instafail:让测试失败信息即时反馈

pytest-instafail&#xff1a;让测试失败信息即时反馈 前言一、简介二、优势三、安装与使用3.1 未安装时运行情况3.2 安装3.3 已安装时运行情况3.3 pytest.ini 配置选项 四、对比 总结 前言 当测试用例数量庞大时&#xff0c;定位测试失败的原因往往耗时费力。此时&#xff0c;…

从 0 开始实现一个 SpringBoot + Vue 项目

从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口 Model 层mapper 层service 层controller 层测试 实现项目功能接口 代码测试 创建 Vue 前端 安装 Node.js配置…

5. 推荐算法的最基础和最直观的认识

1.性别年龄转换为统一的计量单位 所谓推荐&#xff0c;就是替别人推荐&#xff0c;比如工厂A需要招男员工&#xff0c;希望大家推荐认识的人。那么在这里&#xff0c;就有了推荐的概念&#xff0c;限定条件是男。我们知道&#xff0c;人的性别一般分为男或者女。在这里假设把男…

ASP.NET Core - 配置系统之配置添加

ASP.NET Core - 配置系统之配置添加 2. 配置添加 2. 配置添加 配置系统可以读取到配置文件中的信息&#xff0c;那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中&#xff0c;builder(WebApplicationBuilder 对象) 中有一个 Config…

AI编程工具横向评测--Cloudstudio塑造完全态的jupyter notebook助力数据分析应用开发

AI编程工具横向评测–Cloudstudio塑造完全态的jupyter notebook助力数据分析应用开发 数据分析类应用的开发&#xff0c;指的是首先进行数据分析&#xff0c;比如统计学分析、机器学习模型的构建等&#xff0c;然后将分析的流程开发成数据分析类的工具&#xff0c;或者将数据分…

HBase实训:纸币冠字号查询任务

一、实验目的 1. 理解分布式数据存储系统HBase的架构和工作原理。 2. 掌握HBase表的设计原则&#xff0c;能够根据实际业务需求设计合理的表结构。 3. 学习使用HBase Java API进行数据的插入、查询和管理。 4. 实践分布式数据存储系统在大数据环境下的应用&#xff0c;…

算法与数据结构——复杂度

目录 一 数据结构前言 1 数据结构 2 算法 3 算法与数据结构的关系 二 算法效率 1 算法效率&#xff1a; 2 复杂度 2.1 概念&#xff1a; 2.2分类&#xff1a; 2.3 空间复杂度在计算机高速发展的现代重要吗&#xff1f; 3 复杂度的重要性 三 时间复杂度…

usb通过hdc连接鸿蒙next的常用指令

参考官方 注册报名https://www.hiascend.com/developer/activities/details/44de441ef599450596131c8cb52f7f8c/signup?channelCodeS1&recommended496144 hdc-调试命令-调测调优-系统 - 华为HarmonyOS开发者https://developer.huawei.com/consumer/cn/doc/harmonyos-guid…

论文笔记-arXiv2025-A survey about Cold Start Recommendation

论文笔记-arXiv2025-Cold-Start Recommendation towards the Era of Large Language Models: A Comprehensive Survey and Roadmap 面向大语言模型&#xff08;LLMs&#xff09;时代的冷启动推荐&#xff1a;全面调研与路线图1.引言2.前言3.内容特征3.1数据不完整学习3.1.1鲁棒…

如何将数据库字符集改为中文,让今后所有的数据库都支持中文

最后一行有我自己的my.ini文件 数据库输入中文数据时会变为乱码&#xff0c; 这个时候&#xff0c;我们为每个数据库设置字符集&#xff0c;太过于麻烦&#xff0c;为数据库单独设置重启后又会消失 Set character_set_database’utf8’; Set character_set_server’utf8’; …

AI刷题-小R的随机播放顺序、不同整数的计数问题

目录 一、小R的随机播放顺序 问题描述 测试样例 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 最终代码&#xff1a; 运行结果&#xff1a; 二、 不同整数的计数问题 问题描述 测试样例 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 最终…

从零搭建SpringBoot3+Vue3前后端分离项目基座,中小项目可用

文章目录 1. 后端项目搭建 1.1 环境准备1.2 数据表准备1.3 SpringBoot3项目创建1.4 MySql环境整合&#xff0c;使用druid连接池1.5 整合mybatis-plus 1.5.1 引入mybatis-plus1.5.2 配置代码生成器1.5.3 配置分页插件 1.6 整合swagger3&#xff08;knife4j&#xff09; 1.6.1 整…

在.NET用C#将Word文档转换为HTML格式

将Word文档转换为HTML格式尤其具有显著的优势&#xff0c;它不仅能够确保文档内容在多种设备和平台上保持一致灵活的显示&#xff0c;还便于通过网络进行传播和集成到各种Web应用中。随着越来越多的企业和开发者寻求更灵活、更具兼容性的文件处理方式&#xff0c;.NET框架下的C…