RapidJSON简介及使用

Posted Fu_Lin_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RapidJSON简介及使用相关的知识,希望对你有一定的参考价值。

前言

RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及ios, android。它的源码在【】https://github.com/Tencent/rapidjson/,稳定版本为2016年发布的1.1.0版本。 官网地址

RapidJSON特点

  1. RapidJSON小而全:它同时支持SAX和DOM风格的API,SAX解析器只有约500行代码。
  2. RapidJSON快:它的性能可与strlen()相比,可支持SSE2/SSE4.2加速,使用模版及内联函数去降低函数调用开销。
  3. RapidJSON独立:它不依赖于BOOST等外部库,它甚至不依赖于STL。
  4. RapidJSON对内存友好:在大部分32/64位机器上,每个JSON值只占16字节(除字符串外),它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
  5. RapidJSON对Unicode友好:它支持UTF-8、UTF-16、UTF-32(大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON可以在分析一个UTF-8文件至DOM (Document Object Model, 文件对象模型)时,把当中的JSON字符串转码至UTF-16。它也支持代理对(surrogate pair)及"\\u0000"(空字符)。

每个JSON值都储存为Value类,而Document类则表示整个DOM,它存储了一个DOM 树的根Value。RapidJSON的所有公开类型及函数都在rapidjson命名空间中。

以上内容摘自:官网,关于RapidJSON的更详细介绍可以参考此网页。

测试代码

以下是测试代码(test_rapidjson.cpp):

#include "funset.hpp"
#include "rapidjson/document.h"
//#include "rapidjson/writer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <fstream>
#include <string>
#include "common.hpp"
 
int test_rapidjson_parse()
{
#ifdef _MSC_VER
	const char* file_name = "E:/GitCode/Messy_Test/testdata/json.data";
#else
	const char* file_name = "testdata/json.data";
#endif
	std::ifstream in(file_name);
	if (!in.is_open()) {
		fprintf(stderr, "fail to read json file: %s\\n", file_name);
		return -1;
	}
 
	std::string json_content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
	in.close();
 
	rapidjson::Document dom;
	if (!dom.Parse(json_content.c_str()).HasParseError()) {
		if (dom.HasMember("name") && dom["name"].IsString()) {
			fprintf(stdout, "name: %s\\n", dom["name"].GetString());
		}
 
		if (dom.HasMember("address") && dom["address"].IsString()) {
			fprintf(stdout, "address: %s\\n", utf8_to_gbk(dom["address"].GetString()));
		}
 
		if (dom.HasMember("age") && dom["age"].IsInt()) {
			fprintf(stdout, "age: %d\\n", dom["age"].GetInt());
		}
 
		const char* tmp = "xxx";
		if (!dom.HasMember(tmp)) {
			fprintf(stdout, "Warning: it has no member: %s\\n", tmp);
		}
 
		if (dom.HasMember("value1") && dom["value1"].IsArray()) {
			const rapidjson::Value& arr = dom["value1"];
			for (int i = 0; i < arr.Size(); ++i) {
				const rapidjson::Value& tmp = arr[i];
				
				fprintf(stdout, "value1:\\ni = %d:", i);
				for (int j = 0; j < tmp.Size(); ++j) {
					if (tmp[j].IsInt())
						fprintf(stdout, "%d, ", tmp[j].GetInt());
					if (tmp[j].IsFloat())
						fprintf(stdout, "%.1f, ", tmp[j].GetFloat());
				}
				fprintf(stdout, "\\n");
			}
		}
 
		if (dom.HasMember("value2") && dom["value2"].IsArray()) {
			const rapidjson::Value& arr = dom["value2"];
 
			fprintf(stdout, "value2: ");
			for (int i = 0; i < arr.Size(); ++i) {
				fprintf(stdout, "%.2f, ", arr[i].GetFloat());
			}
			fprintf(stdout, "\\n");
		}
 
		if (dom.HasMember("bei_jing") && dom["bei_jing"].IsObject()) {
			const rapidjson::Value& obj = dom["bei_jing"];
 
			if (obj.HasMember("address") && obj["address"].IsString()) {
				fprintf(stdout, "address: %s\\n", utf8_to_gbk(obj["address"].GetString()));
			}
 
			if (obj.HasMember("car") && obj["car"].IsBool()) {
				fprintf(stdout, "car: %d\\n", obj["car"].GetBool());
			}
 
			if (obj.HasMember("cat") && obj["cat"].IsBool()) {
				fprintf(stdout, "cat: %d\\n", obj["cat"].GetBool());
			}
		}
 
		if (dom.HasMember("shan_dong") && dom["shan_dong"].IsObject()) {
			const rapidjson::Value& obj = dom["shan_dong"];
 
			if (obj.HasMember("address") && obj["address"].IsString()) {
				fprintf(stdout, "address: %s\\n", utf8_to_gbk(obj["address"].GetString()));
			}
 
			if (obj.HasMember("value1") && obj["value1"].IsArray()) {
				const rapidjson::Value& arr = obj["value1"];
 
				if (arr[0].HasMember("ji_nan") && arr[0]["ji_nan"].IsString()) {
					fprintf(stdout, "ji_nan: %s\\n", utf8_to_gbk(arr[0]["ji_nan"].GetString()));
				}
 
				if (arr[0].HasMember("tai_an") && arr[0]["tai_an"].IsString()) {
					fprintf(stdout, "tai_an: %s\\n", utf8_to_gbk(arr[0]["tai_an"].GetString()));
				}
			}
		}
	} else {
		fprintf(stderr, "fail to parse json file: %s\\n", file_name);
		return -1;
	}
 
	// iter json
	for (rapidjson::Value::ConstMemberIterator iter = dom.MemberBegin(); iter != dom.MemberEnd(); ++iter) {
		fprintf(stdout, "iter json name: %s, type: %d\\n", iter->name.GetString(), iter->value.GetType());
	}
 
	return 0;
}
 
int test_rapidjson_write()
{
	rapidjson::StringBuffer buf;
	//rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
	rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrap
 
	writer.StartObject();
 
	writer.Key("name"); writer.String("spring");
	writer.Key("address"); writer.String("北京");
	writer.Key("age"); writer.Int(30);
 
	writer.Key("value1");
	writer.StartArray();
	writer.StartArray();
 
	writer.StartObject();
 
	writer.Key("name"); writer.String("spring");
	writer.Key("address"); writer.String("北京");
	writer.Key("age"); writer.Int(30);
 
	writer.Key("value1");
	writer.StartArray();
	writer.StartArray();
	writer.Double(23); writer.Double(43); writer.Double(-2.3); writer.Double(6.7);     
    writer.Double(90);
	writer.EndArray();
 
	writer.StartArray();
	writer.Int(-9); writer.Int(-19); writer.Int(10); writer.Int(2);
	writer.EndArray();
 
	writer.StartArray();
	writer.Int(-5); writer.Int(-55);
	writer.EndArray();
	writer.EndArray();
 
	writer.Key("value2");
	writer.StartArray();
	writer.Double(13.3); writer.Double(1.9); writer.Double(2.10);
	writer.EndArray();
 
	writer.Key("bei_jing");
	writer.StartObject();
	writer.Key("address"); writer.String("海淀");
	writer.Key("car"); writer.Bool(false);
	writer.Key("cat"); writer.Bool(true);
	writer.EndObject();
 
	writer.Key("shan_dong");
	writer.StartObject();
	writer.Key("address"); writer.String("济南");
	writer.Key("value1");
	writer.StartArray();
	writer.Key("ji_nan"); writer.String("趵突泉");
	writer.Key("tai_an"); writer.String("泰山");
	writer.EndArray();
	writer.EndObject();
 
	writer.EndObject();
 
	const char* json_content = buf.GetString();
	fprintf(stdout, "json content: %s\\n", json_content);
 
#ifdef _MSC_VER
	const char* file_name = "E:/GitCode/Messy_Test/testdata/out.json";
#else
	const char* file_name = "testdata/out.json";
#endif
	std::ofstream outfile;
	outfile.open(file_name);
	if (!outfile.is_open()) {
		fprintf(stderr, "fail to open file to write: %s\\n", file_name);
		return -1;
	}
 
	outfile << json_content << std::endl;
	outfile.close();
 
	return 0;
}

json.data内容如下:

{
  "name": "spring",
  "address": "北京",
  "age": 30,
  "value1": [[23, 43, -2.3, 6.7, 90],
             [-9, -19, 10, 2],
             [-5, -55]],
  "value2": [13.3, 1.9, 2.10],
  
  "bei_jing": {
    "address": "海淀",
    "car": false,
    "cat": true
  },
  "shan_dong": {
    "address": "济南",
    "value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
  }
}

test_rapidjson_parse 的执行结果如下:与实际结果一致
在这里插入图片描述
test_rapidjson_write的执行结果如下:与预期一致,将 rapidjson::Writer<rapidjson::StringBuffer> writer(buf) 调整为 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf) ;可使结果自动换行
在这里插入图片描述

其他demo案例

RapidJson使用范例(DOM解析json字符串并修改json中指定元素的值)

#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

using namespace std;
using namespace rapidjson;

int main(int argv ,char *argc[])
{
  //1.把JSON解析至DOM
  const char * strJson = "{\\"key1\\":\\"value1\\",\\"key2\\":\\"value2\\",\\"key3\\":100}";
  Document doc;
  doc.Parse(strJson);
  cout<< strJson << endl;
  //2.利用DOM作出修改
  Value& v1 = doc["key2"];
  v1="value_modify";
  //v1.SetString("value_modify");  
  Value& v2 = doc["key3"];
  v2.SetInt(v2.GetInt()+1);
  //SetString()
  //SetBool()
  //SetUint()
  //SetInt64()
  //SetUInt64()
  以上是关于RapidJSON简介及使用的主要内容,如果未能解决你的问题,请参考以下文章

RapidJSON解析数组

rapidjson使用总结

rapidjson的学习及使用

rapidjson安装使用

rapidjson安装使用

RapidJson:错误 C2061:语法错误:标识符“stack_”