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