动态

详情 返回 返回

簡單、穩定、概念前衞且易看懂的JSON庫——QJSON - 动态 详情

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

Add a new 评论

Some HTML is okay.