由于偏向C++语言,不像java有那样多的jar包直接调用。最近频繁使用json文件。采用了tencent开源的RapidJSON库,介绍不再多说,好处是跨平台,只需引用头文件即可用。
因为平时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:
关于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 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的解析下篇在记录吧