由於偏向C++語言,不像java有那樣多的jar包直接調用。最近頻繁使用json文件。採用了tencent開源的RapidJSON庫,介紹不再多說,好處是跨平臺,只需引用頭文件即可用。
因爲平時json格式用的不多,只需要基本的增添,解析,生成,刪除等基本操作,想要在不深究的情況下順利使用。找了很多資料,描述很少。就想結合最近的使用做一下記錄。
- json串格式
//我要解析的json串
{
"test": {
"camera": {
"camera1": {
"height": 111,
"deviationAngle": 222,
"visualAngleX": 333,
"visualAngleY": 44,
"pixelWidth": 1234,
"pixelHeight": 1234,
"xaxisToLaster": 111
},
"camera2": {
"height": 1000,
"deviationAngle": 1.1,
"visualAngleX": 58.32,
"visualAngleY": 23.34,
"pixelWidth": 1000,
"pixelHeight": 2000,
"xaxisToLaster": 220
},
"camera3": {
"height": 1430,
"deviationAngle": 5.06,
"visualAngleX": 57.8,
"visualAngleY": 32,
"pixelWidth": 1520,
"pixelHeight": 1080,
"xaxisToLaster": 110
}
}
}
}
可以看出json串的特點是,三層json的嵌套。
使用情景是,在已有json文件時,想要添加一組新的json數據,大概步驟:
- 讀原始json文件,返回string類型進行後續處理
- 根據新的value生成新json串,轉化成string類型
- 寫文件,插入原json文件中。
如何生成這樣格式的json:
關於ReadJson()和writeFiles()兩個json的讀寫函數 請移步:https://blog.csdn.net/Hu_helloworld/article/details/97626860
string readStr = jsonUtil::ReadJson();
Document doc, docCamera, docPtr;
doc.SetObject();
docCamera.SetObject();
docPtr.SetObject();
Document::AllocatorType& allocator = docPtr.GetAllocator();
docPtr.Parse(readStr.c_str()); //Parse()讀取json字符串,再進行解析
if (!docPtr.HasMember(test.toStdString().c_str())) //查詢原json文件,若沒有test成員,生成
{
Value CameraObj(kObjectType); //從最內層的"camera1"開始,層層包裹
CameraObj.AddMember("height", saveDouble(g_cameraHeight), allocator);
CameraObj.AddMember("deviationAngle", saveDouble(g_deviationAngle), allocator);
CameraObj.AddMember("visualAngleX", saveDouble(g_visualAngleX), allocator);
CameraObj.AddMember("visualAngleY", saveDouble(g_visualAngleY), allocator);
CameraObj.AddMember("pixelWidth", pixelWidth.toDouble(), allocator);
CameraObj.AddMember("pixelHeight", pixelHeight.toDouble(), allocator);
CameraObj.AddMember("Laster", saveDouble(g_xaxisToLaster), allocator);
Value camera_key(cameraId.toStdString().c_str(), allocator);
doc.AddMember(camera_key, CameraObj, allocator); //"camera1"層object
docCamera.AddMember("camera", doc, allocator); //"camera"層object
Value robot_key(Robot.toStdString().c_str(), allocator); //傳遞key變量
docPtr.AddMember(robot_key, docCamera, allocator); //最外層object
StringBuffer str_buf;
PrettyWriter<StringBuffer> writer(str_buf);
docPtr.Accept(writer);
cout << str_buf.GetString() << endl;
jsonUtil::writeFiles(str_buf.GetString());
}
重要的是理清楚json嵌套的層級
有一個小坑是在用 AddMember方法添加成員時。可以發現AddMember有7個重載類型。
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator)
而第一個參數name,只有兩種:StringRefType和GenericValue< Encoding, Allocator >
官方文檔對於StringRefType的解釋是:Reference to a constant string (引用的常量字符串)
所以若通過要傳遞的key是用戶鍵入的變量,需要轉成Value類型
即:
Value robot_key(YD_Robot.toStdString().c_str(), allocator); //傳遞key變量
docPtr.AddMember(robot_key, docCamera, allocator);
若傳遞固定的常量:
docPtr.AddMember(“xiaoming”, docCamera, allocator); 即可。
Rapidjson的解析下篇在記錄吧