RapidJSON生成、解析多層嵌套的複雜json

由於偏向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數據,大概步驟:

  1. 讀原始json文件,返回string類型進行後續處理
  2. 根據新的value生成新json串,轉化成string類型
  3. 寫文件,插入原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的解析下篇在記錄吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章