首页 > 编程语言 >C++序列化封装EasySerialize

C++序列化封装EasySerialize

时间:2023-08-19 18:11:07浏览次数:50  
标签:xml EasySerialize struct C++ 链表 XmlElement 序列化 节点

    最近在做C++项目,需要序列化和反序列化json以及xml数据。可能是由于用惯了C#等更高度化语言,搜了一遍,发现C++没有特别方便使用的序列化、反序列化的库。大部分库都是为了实现功能(非常感谢这些实现库的作者),使用时,需要根据字段深度定义结构体字段(这一步无法省略),然后再使用手动编写方式进行json/xml对字段进行赋值。因此,在使用便捷上,比C#、JAVA等还是略差一筹。其中,有一个库(忘了名字)实现了通过在结构体最后面定义一个宏罗列所有字段的方式,省略了手动编写赋值的麻烦,易用性提升了一步,但仍然存在一个问题,就是结构体字段比较多时,经常忘记定义字段和宏枚举之间要一并处理,因此,使用上,比C#、JAVA还是略差一筹。

    基于以上问题,本人对已有开源的json、xml功能实现库进行二次封装,赋予功能实现库更便捷的使用。其中,json使用jsoncpp开源库,xml使用 tinyxml2开源库,开源库地址:

json:https://github.com/open-source-parsers/jsoncpp

xml:https://github.com/leethomason/tinyxml2

    本人二次封装的源码地址:

EasySerialize:https://files.cnblogs.com/files/blogs/476708/EasySerialize.zip?t=1692439662&download=true

基于这两个开源库,再进行简单封装,达到只需要按格式定义结构体,不需要编写赋值的实现效果。详细使用,请查源码中的测试列子。

1、XML

    xml分为两种节点: Element 和 Attribute 。分别对应xml的内容节点和属性。定义xml的结构体时,需根据实际的xml文件格式定义。

    xml节点分为 简单节点、复杂单节点、链表节点 三种。

1)简单节点:此节点 没有属性,其内容也没有保护其他复杂节点(即内容是简单的字符串),使用XmlString、XmlInt32、XmlBool等基本xml类型表示。下面 str1 和 int2 节点都属于简单节点。

<testxml>
    <str1>test1</str1>
    <int2>200</int2>
</testxml>

EasySerialize的xml结构体表示:

struct XmlInfo : XmlBase
{

    XmlString str1    XmlElement("str1");
    XmlInt32 int2     XmlElement("int2");
};

说明:XmlString表示str1节点的内容是string类型,为简单节点类型,但其本身是一个 Element 类型的节点,而非属性。同理,int2也是简单节点,但其内容为int32类型,其本身也是一个xml节点。

2)复杂的单节点:节点内容是复杂的,嵌套了其他的节点,或者带了属性,但没有同名的兄弟节点,使用XmlObject<T>表示。下面 obj1属于复杂单节点。

<testxml>
    <obj1>
        <element1>objele1</element1>
        <element2>255</element2>
        <element3 attr1="testattr1" attr2="500">content_with_attr</element3>
    </obj1>
</testxml>

EasySerialize的xml结构体表示:

struct SimpleNode2 : XmlBase
{
    XmlString ContentWithAttribute       XmlSimpleContent("simplenode2");
    XmlString Attribute1                         XmlAttribute("attr1");
    XmlInt32  Attribute2                         XmlAttribute("attr2");
};

struct ObjectNode : XmlBase
{
    XmlString Element1                              XmlElement("element1");
    XmlInt32  Element2                               XmlElement("element2");
    XmlObject<SimpleNode2> Element3    XmlElement("element3");
};

struct XmlInfo : XmlBase
{
    XmlObject<ObjectNode> obj1 XmlElement("obj1");
};

说明:obj1是一个复杂的单节点,里面又包含了3个element,而其中Element3又是一个复杂节点,因为它带了属性。例子中,除了element外,还有attr1和attr2为属性节点,而ContentWithAttribute,它只是为了存储element3的内容(即例子中的content_with_attr),此内容为string类型,并且既不是element节点,也不是attribute节点,因此,定义为XmlSimpleContent。

3)链表节点:存在同名的兄弟节点,则为链表节点,使用XmlArray<T>表示。下面item节点为链表节点,每个item为链表的一个元素。

<testxml>
    <obj2>
        <item>item1content</item>
        <item>item2content</item>
        <item>item3content</item>
    </obj2>
</testxml>

EasySerialize的xml结构体表示:

struct SimpleNode1 : XmlBase
{
XmlString OnlyContent XmlSimpleContent("simplenode1");
};

struct ObjectArr : XmlBase
{
XmlArray<SimpleNode1> Arrays XmlElement("item");
};

struct XmlInfo : XmlBase
{
XmlObject<ObjectArr> obj2 XmlElement("obj2");
};

说明:obj2本身是一个复杂的单节点(因为它没有同名的兄弟节点,因此不是链表,但其内容是复杂内容),其内容为一个链表节点,而每个元素节点都是简单节点。

2、json

    json相对简单,直接查看源码例子即可。

 

标签:xml,EasySerialize,struct,C++,链表,XmlElement,序列化,节点
From: https://www.cnblogs.com/lishide/p/17642833.html

相关文章

  • 24届C++后端开发八月面经
    百度提前批一面项目:日志模块,如何实现保证写入和非保证写入如何保证日志时间的实时性?不用文件大小作为文件滚动的标注,而是使用时间作为标识更加符合查看日志的需求webserver如何与MYSQL数据库进行交互?当有非常多的并发量,如何进行一个MYSQL底层存储的优化?记录用户uid最......
  • c++ 面试整理
    如何理解封装、继承、多态封装可以隐藏实现细节,使得代码模块化;封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。多态多态指同一个实......
  • 二分搜索法-C++
    二分法,就是对一个数组中,已经排好序的数字进行搜索。使用二分法的前提条件:1.是一个数组2.该数组中的数字已经是有序的,比如升序的数字或者降序的数字都可以。inta[]={1,2,3,4};   intb[]={4,3,2,1};3.该数组中没有出现重复的数字 二分法原理:就是对一个数组,不断的划分......
  • C++问题汇总
    一、执行C++程序报错1、现象#现象./gtest_W:/lib64/libstdc++.so.6:version`GLIBCXX_3.4.20'notfound(requiredby./gtest_W)./gtest_W:/lib64/libstdc++.so.6:version`CXXABI_1.3.9'notfound(requiredby./gtest_W)./gtest_W:/lib64/libstdc++.so.6:version......
  • C++入门到放弃(11)——继承
    ​继承是面向对象编程语言当中,最重要的部分,也是代码重用的一种重要形式。不知道为啥不能添加代码了,全部只能用图片替代了。1.基本形式首先继承的有三种基本形式,分别是public、private、protected,代表公有继承、私有继承和保护继承,之前在介绍作用范围的时候提过这三者的区别,但这......
  • VScode软件的安装以及C/C++环境配置的方法
    今天和大家分享一下VScode软件的安装以及C/C++环境配置的方法。手把手教大家入门。1,下载VScode编译器(1)   官网下载链接:https://code.visualstudio.com/ (2)安装VScode。安装过程中的附加任务建议全部勾选。 至此VScode安装完成 2,下载编译器MinGW。(1)下载地址:https:......
  • c++ 多线程
    #include<iostream>#include<functional>#include<thread>#include<future>//std::promise,std::future#include<chrono>voidprint_int(std::future<int>&fut){intx=fut.get();......
  • 如何在C++程序中借助Windows自带的bitsadmin命令从123云盘(不开通直链或会员)上下载文件
    最近,我想发布一个程序,里面想嵌入一些比较大的文件,但是如果直接用资源方式嵌入的话程序的体积就非常大,所以我想用从网上下载的方式获取这些文件。之前我试过很多方式,都没有成功,最后找到了这种方式...准备工作:先了解一下bitsadmin命令的语法,详见官方文档https://learn.microsof......
  • c++[1]
    命名空间:为什么要使用命名空间?使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,于是就有了关键字namespace举个例子:#include<iostream>#include<stdlib.h>//头文件中包含rand函数的定义intrand=10;//命名冲突intmain(){ printf("%d",rand);......
  • C++中String的语法及常用接口用法
    在C语言中,string是一个标准库类(class),用于处理字符串,它提供了一种更高级、更便捷的字符串操作方式,string 类提供了一系列成员函数和重载运算符,以便于对字符串进行操作和处理。一、string类在学习string前,我们不妨先来了解一下string类到底是什么,有什么用呢?我们先来了解一下基本......