C++ 使用 rapidjson 生成 json 並解析

  • 2019 年 11 月 6 日
  • 筆記

概述

使用 rapidjson 生成 json 並對其進行解析。

常用函數

AddMember

  • 功能:往對象中添加一個鍵值對。GenericValue& rapidjson::GenericValue< Encoding, Allocator >::AddMember( GenericValue< Encoding, Allocator > & name, GenericValue< Encoding, Allocator > & value, Allocator & allocator )
  • 函數原型
  • 函數參數
    • name 是鍵的名稱
    • value 是對應鍵的值
    • allocator 用來分配記憶體的分配器,必須與前面使用的相同。

SetString

  • 功能:將此值設置為字元串,且複製原字元串。
  • 函數原型
GenericValue& rapidjson::GenericValue< Encoding, Allocator >::SetString(  const Ch * 	s,  SizeType 	length,  Allocator & 	allocator  )			
  • 函數參數
    • s 是原字元串
    • length 是原字元串的長度,包括後面的空字元
    • allocator 分配器

程式碼

#include <iostream>  #include <string>  #include <fstream>  #include <windows.h>  #include "rapidjson/prettywriter.h"  #include "rapidjson/document.h"  #include "rapidjson/istreamwrapper.h"    using namespace std;  using namespace rapidjson;    //-----------------------------------------------------------------------------  void AddBasicType(Document &d, Document::AllocatorType & allocator)  {  	d.AddMember("digit", 3, allocator);           // 添加整型數據  	d.AddMember("height", 170.5, allocator);      // 添加浮點類型  	d.AddMember("subject1", "math", allocator);   // 添加字元串類型,常量方式    	string strSubject = "English";  	Value valueSubject(kStringType);  	valueSubject.SetString(strSubject.c_str(), strSubject.size(), allocator);    	if (!valueSubject.IsNull())  	{  		d.AddMember("subject2", valueSubject, allocator); // 添加字元串類型,變數方式,不能直接對變數進行添加,類型不對  	}  }    //-----------------------------------------------------------------------------  void AddObjectType(Document &d, Document::AllocatorType & allocator)  {  	Value valueObject(kObjectType);  	valueObject.AddMember("sex", "male", allocator);  	valueObject.AddMember("weight", 95, allocator);  	d.AddMember("info", valueObject, allocator);  }    //-----------------------------------------------------------------------------  void AddStringArrayType(Document &d, Document::AllocatorType & allocator)  {  	Value valueStr(kStringType);      // 單個字元串  	Value valueStrArray(kArrayType);  // 字元串數組    	string strExtraSubject1 = "電腦";  	string strExtraSubject2 = "音樂";  	string strExtraSubject3 = "體育";    	valueStr.SetString(strExtraSubject1.c_str(), strExtraSubject1.size(), allocator);  	valueStrArray.PushBack(valueStr, allocator);    	valueStr.SetString(strExtraSubject2.c_str(), strExtraSubject2.size(), allocator);  	valueStrArray.PushBack(valueStr, allocator);    	valueStr.SetString(strExtraSubject3.c_str(), strExtraSubject3.size(), allocator);  	valueStrArray.PushBack(valueStr, allocator);    	d.AddMember("extraSubject", valueStrArray, allocator);  }    //-----------------------------------------------------------------------------  void AddObjectArrayType(Document &d, Document::AllocatorType & allocator)  {  	Value valueObjectArray(kArrayType);  	for (int i = 0; i < 3; i++)  	{  		Value valueSingleObject(kObjectType);  		valueSingleObject.AddMember("score", i * 40, allocator);  		if (i == 0)  		{  			valueSingleObject.AddMember("difficulty", "hard", allocator);  		}  		else if (i == 1)  		{  			valueSingleObject.AddMember("difficulty", "abnormal", allocator);  		}  		else  		{  			valueSingleObject.AddMember("difficulty", "easy", allocator);  		}  		valueObjectArray.PushBack(valueSingleObject, allocator);  	}  	d.AddMember("subjectInfo", valueObjectArray, allocator);  }    //-----------------------------------------------------------------------------  void ParseBasicType(Document &d, string jsonData)  {  	if (!d.Parse(jsonData.data()).HasParseError())  	{  		// 解析整型  		if (d.HasMember("digit") && d["digit"].IsInt())  		{  			cout << "digit = " << d["digit"].GetInt() << endl;  		}    		// 解析浮點型  		if (d.HasMember("height") && d["height"].IsDouble())  		{  			cout << "height = " << d["height"].GetDouble() << endl;  		}    		// 解析字元串類型  		if (d.HasMember("subject1") && d["subject1"].IsString())  		{  			cout << "subject1 = " << d["subject1"].GetString() << endl;  		}    		if (d.HasMember("subject2") && d["subject1"].IsString())  		{  			cout << "subject2 = " << d["subject2"].GetString() << endl;  		}  	}  }    //-----------------------------------------------------------------------------  void ParseObjectType(Document &d, string jsonData)  {  	if (d.HasMember("info") && d["info"].IsObject())  	{  		const Value& resInfo = d["info"]; // 獲取對象  		if (resInfo.HasMember("sex") && resInfo["sex"].IsString())  		{  			cout << "resInfo.sex = " << resInfo["sex"].GetString() << endl;  		}  		if (resInfo.HasMember("weight") && resInfo["weight"].IsInt())  		{  			cout << "resInfo.weight = " << resInfo["weight"].GetInt() << endl;  		}  	}  }    //-----------------------------------------------------------------------------  void ParseStringArrayType(Document &d, string jsonData)  {  	if (d.HasMember("extraSubject") && d["extraSubject"].IsArray())  	{  		const Value& valueStrArray = d["extraSubject"];  		size_t len = valueStrArray.Size(); // 獲取數組長度    		for (size_t i = 0; i < len; i++)  		{  			cout << "extraSubject[" << i << "] = " << valueStrArray[i].GetString() << endl;  		}  	}  }    //-----------------------------------------------------------------------------  void ParseObjectArrayType(Document &d, string jsonData)  {  	if (d.HasMember("subjectInfo") && d["subjectInfo"].IsArray())  	{  		const Value& valueObjectArray = d["subjectInfo"]; // 獲取對象數組  		size_t len = valueObjectArray.Size();  		for (size_t i = 0; i < len; i++)  		{  			const Value& object = valueObjectArray[i]; // 每一個元素都是一個對象    			if (object.IsObject())  			{  				cout << "subjectInfo[" << i << "]: ";  				if (object.HasMember("score") && object["score"].IsInt())  				{  					cout << "score = " << object["score"].GetInt();  				}  				if (object.HasMember("difficulty") && object["difficulty"].IsString())  				{  					cout << " difficulty = " << object["difficulty"].GetString();  				}  			}  			cout << endl;  		}  	}  }    //-----------------------------------------------------------------------------  int main()  {  	Document d;  	d.SetObject();  	wstring wsValue;  	Document::AllocatorType &allocator = d.GetAllocator(); // 獲取分配器    	AddBasicType(d, allocator);         // 添加基本類型  	AddObjectType(d, allocator); 	    // 添加對象類型,對象中有基本數據類型  	AddStringArrayType(d, allocator);	// 添加字元串數組類型,數組中的每一個元素是一個字元串  	AddObjectArrayType(d, allocator);	// 添加對象數組類型,數組中的每一個元素是一個對象    	// StringBuffer是一個簡單的輸出流。它分配一個記憶體緩衝區,供寫入整個JSON。  	// 可使用GetString()來獲取該緩衝區。  	StringBuffer strBuf;  	Writer<StringBuffer> writer(strBuf);  	d.Accept(writer);    	string jsonData = strBuf.GetString();  	cout << jsonData << endl << endl;    	ParseBasicType(d, jsonData);		// 解析基本類型  	ParseObjectType(d, jsonData);		// 解析對象類型  	ParseStringArrayType(d, jsonData);	// 解析字元串數組類型  	ParseObjectArrayType(d, jsonData);	// 解析對象數組類型  }

生成的 json 數據

{    "digit": 3,    "height": 170.5,    "subject1": "math",    "subject2": "English",    "info": {      "sex": "male",      "weight": 95    },    "extraSubject": [      "電腦",      "音樂",      "體育"    ],    "subjectInfo": [      {        "score": 0,        "difficulty": "hard"      },      {        "score": 40,        "difficulty": "abnormal"      },      {        "score": 80,        "difficulty": "easy"      }    ]  }

參考資料