头图

QJSON

介绍

QJSON 是 ZJSON的替代库。
ZJSON已经开发出来有一段时间了,也进行了一些应用,效果还不错,但现在存在些问题。

  • 字符串解析为json对象时,当初借鉴于json11,一直没时间去换成状态机模式
  • 没有进行大规模数据验证
  • 大量使用递归算法,没时间组织测试
  • C++要求至少为 C++17 版本

因此花了一个国庆假期,封装QT5:Core中的相关Json库,保持与ZJSON相同的外部接口,以求解决以上问题。

设计思路

简单的接口函数、简单的使用方法、增加支持链式操作。
使用模板技术,使用给Json对象增加值的方法只需要一个 --- add。底层使用QT5:Core中的相关Json库,保证稳定性,C++版本要求高于c++11。
使用简单,项目为单文件结构,只需要引入qjson.h,并链接上QT5:Core即可。
完全符合Json标准,对外一个Json对象,要么为Object,要么为Array。但Json对象实际上可以有 纯值 类型(包括Error类型),这是为了适应链式操作的场景,并且让查找等操作可以统一返回Json对象,让所有的操作尽量达到一致性。

项目进度

项目目前完成大部分主要功能,具体情况请看任务列表,同时支持windws、linux和mac主流操作系统。
任务列表:

  • [x] 构造函数(Object & Array)
  • [x] 构造函数(值)
  • [x] JSON字符串反序列化构造函数
  • [x] 复制构造函数
  • [x] initializer_list构造函数
  • [x] 析构函数
  • [x] operator=
  • [x] operator==
  • [x] operator!=
  • [x] operator[]
  • [x] contains
  • [x] getValueType
  • [x] getAllKeys
  • [x] add(为Json对象增加子对象,为数组快速增加元素)
  • [x] toString(生成json字符串)
  • [x] toInt、toDouble、toFalse 等值类型转换
  • [x] toVector 数组类型转换
  • [x] isError、isNull、isArray 等节点类型判断
  • [x] parse, 从json字符串生成Json对象
  • [x] extend Json - 扩展对象
  • [x] concat Json - 数组扩展
  • [x] push_front - 数组压入队首
  • [x] push_back - 数组压入队尾
  • [x] pop_front - 数组弹出队首
  • [x] pop_back - 数组弹出队尾
  • [x] take - 获取并删除
  • [x] first - 获取数组第一个
  • [x] last - 获取数组最后一个
  • [x] slice - 数组取出子数组
  • [x] insert - 数组插入
  • [x] clear - 清空
  • [x] Remove - 删除
  • [x] RemoveFirst - 删除数组第一个
  • [x] RemoveLast - 删除数组最后一个
  • [x] std::move语义

Json 节点类型定义

(内部使用,数据类型只在Json类内部使用)

enum Type {
    Error,                //错误,查找无果,这是一个无效Json对象
    False,                //Json值类型 - false
    True,                 //Json值类型 - true
    Null,                 //Json值类型 - null
    Number,               //Json值类型 - 数字,库中以double类型存储
    String,               //Json值类型 - 字符串
    Object,               //Json类对象类型 - 这是Object嵌套,对象型中只有child需要关注
    Array                 //Json类对象类型 - 这是Array嵌套,对象型中只有child需要关注
};

Json 节点定义

class Json {
    Type type;
    QJsonDocument* _obj_; //data of object or array
    QString vdata;        //data of number or string
}

接口说明

公开的对象类型,json只支持Object与Array两种对象,与内部类型对应(公开类型)。

enum class JsonType
{
    Object = 6,
    Array = 7
};

编程示例

简单使用示例

    Json subObject{{"math", 99},{"str", "a string."}};   //initializer_list方式构造Json对象

    //initializer_list方式构造Json对象, 并且可以嵌套
    Json mulitListObj{{"fkey", false},{"strkey","ffffff"},{"num2", 9.98}, {"okey", subObject}};

    Json subArray(JsonType::Array);                 //数组对象以initializer_list方式增加元素
    subArray.add({12,13,14,15});             //快速生成 [12,13,14,15] array json

    Json ajson(JsonType::Object);                   //新建Object对象,输入参数可以省略
    std::string data = "kevin";                     
    ajson.add("fail", false)              //增加false值对象
         .add("name", data)               //增加字符串值对象
         .add("school-en", "the 85th.");  //链式调用 
    ajson.add("age", 10);                  //增加number值对象,此处为整数
    ajson.add("scores", 95.98);            //增加number值对象,此处为浮点数,还支持long,long long
         .add("nullkey", nullptr);         //增加null值对象,需要送入nullptr, NULL会被认为是整数0

    Json sub;                                       //新建Object对象
    sub.add("math", 99);                 
    ajson.addValueJson("subJson", sub);             //为ajson增加子Json类型对象,完成嵌套需要

    Json subArray(JsonType::Array);                 //新建Array对象,输入参数不可省略
    subArray.add("I'm the first one.");    //增加Array对象的字符串值子对象
    subArray.add("two", 2);                //增加Array对象的number值子对象,第一个参数会被忽略
    
    Json sub2;                            
    sub2.add("sb2", 222);

    subArray.addValueJson("subObj", sub2);          //为Array对象增加Object类子对象,完成嵌套需求
    
    ajson.addValueJson("array", subArray);          //为ajson增加Array对象,且这个Array对象本身就是一个嵌套结构

    std::cout << "ajson's string is : " << ajson.toString() << std::endl;    //输出ajson对象序列化后的字符串, 结果见下方

    string name = ajson["name"].toString();         //提取key为name的字符串值,结果为:kevin
    int oper = ajson["sb2"].toInt();                //提取嵌套深层结构中的key为sb2的整数值,结果为:222
    Json operArr = ajson["array"];                  //提取key为array的数组对象
    string first = ajson["array"][0].toString();    //提取key为array的数组对象的序号为0的值,结果为:I'm the first one.

mulitListObj序列化后结果为:

{
    "fkey": false,
    "strkey": "ffffff",
    "num2": 9.98,
    "okey": {
        "math": 99,
        "str": "a string."
    }
}

ajson序列化后结果为:

{
    "fail": false,
    "name": "kevin",
    "school-en": "the 85th.",
    "age": 10,
    "scores": 95.98,
    "nullkey": null,
    "subJson": {
        "math": 99
    },
    "array": [
        "I'm the first one.",
        2,
        {
            "sb2": 222
        }
    ]
}

详情请参看相应的测试用例代码。

项目地址

https://gitee.com/zhoutk/qjson
或
https://github.com/zhoutk/qjson

运行方法

该项目在vs2019, gcc7.5, clang12.0下均编译运行正常。

git clone https://github.com/zhoutk/qjson
cd qjson
cmake -Bbuild .

---windows
cd build && cmake --build .

---linux & mac
cd build && make

run qjson or ctest

相关项目

zjson (与本项目保持相同的接口,可互换替换)
https://gitee.com/zhoutk/zjson
或
https://github.com/zhoutk/zjson

zhoutk
2.6k 声望1.2k 粉丝

自由程序员,技术路线c,delphi,c++,c#,java,php,node.js,python,golang,typescript;超喜欢react.js的设计思路,全栈开发成为我的终极目标。开发机器macbook pro,或装ubuntu、fedora的机器,编程用vim...


引用和评论

0 条评论