当前位置: 首页 > 工具软件 > RapidJSON > 使用案例 >

C++的开源JSON开发包 RapidJSON简单使用

艾骏
2023-12-01

1、简介

RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 RapidXml。
RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
RapidJSON 快。它的性能可与 strlen() 相比。可支持 SSE2/SSE4.2 加速。
RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 “\u0000”(空字符)。

2、安装包

去GitHub下载RapidJSON开源包,它的使用只有头文件即可,如果想看例子和doc可以自己用cmake编译一下,否则直接拷贝头文件文件夹rapidjson使用就行了。下载地址:https://download.csdn.net/download/m0_37251750/12341341

3、简单用例

{"info": 
	{"description": "This is v1.0 of the VQA dataset.", 
	"license": 
			{"questions":[
						{"question": "What is the table made of?", 
						"image_id": 350623, 
						"question_id": 3506232}, 
			{"question": "Is the food napping on the table?",
			"image_id": 350623, 
			"question_id": 3506230}]} 
	}
} 

解析获得questions中的question的方法:

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <fstream>
#include <string>
int main()
{
	rapidjson::Document document; // 定义一个Document对象
    std::string str = "";
    document.Parse(str.c_str()); // 解析,Parse()无返回值,也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        // 可通过GetParseError()取得出错代码,
        // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
        // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明,这里的En为English简写
        // 函数GetErrorOffset()返回出错发生的位置
        printf("parse error: (%d:%d)%s\n", document.GetParseError(), document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));
        return -1;
    }
    else
    {
    	if(document.HasMember("info"))
    	{
    		const rapidjson::Value& obj = document["info"];
    		if(obj.HasMember("license"))
   			{
   				const rapidjson::Value& license= obj["license"];
   				if(license.HasMember("questions")&&
   					license["questions"].IsArray())
 				{
	 				auto questions = license["questions"].GetArray();
	   				for(int i=0; i <questions.Size();i++)
	   				{
	   					if(questions[i].HasMember("question")&& 
	   						questions[i]["question"].IsString())
   						{
   							std::string strQuestion = questions[i]["question"].GetString();
   						}
	   				}
 				}				
   			}
    	}
    }
    return 0;
}



for (auto iterEnv = jsonDocument.MemberBegin(); iterEnv != jsonDocument.MemberEnd(); ++iterEnv)
	{
		for (auto iterEnvConfig = iterEnv->value.MemberBegin(); iterEnvConfig != iterEnv->value.MemberEnd(); ++iterEnvConfig)
		{
			std::string currentConfig = iterEnvConfig->name.GetString();
			if (currentConfig == "Types")
			{
				
			}
		}
	}

4、自己简单封装了一个MyJson类如下:

MyJson.h

#pragma once
#ifndef _TEST_JSON_H_
#define _TEST_JSON_H_
// made by ZLY 2020_04_19
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"

#include <iostream>
using namespace std;
using namespace rapidjson;

class MyJson
{
public:
    MyJson(void);
    ~MyJson(void);

    //读取文件
    bool readFile(const char* fileName);

    //写入文件
    bool writeFile(const char* fileName);

    // 添加Value成员
    void addValueMember(const char* key, Value& object);
    void addValueMember(Value& object1,const char* key, Value& object2);

    //添加字符串成员
    void addStrMember(const char* key, const char* value);
    void addStrValue(Value& object,const char* key, const char* value);

    //添加数字成员
    void addIntMember(const char* key, int value);
    void addIntValue(Value& object,const char* key, int value);

    void addFloatMember(const char* key, float value);
    void addFloatValue(Value& object,const char* key, float value);

    void addDoubleMember(const char* key, double value);
    void addDoubleValue(Value& object,const char* key, double value);

    //是否存在成员
    bool hasMember(const char* key);

    //删除成员
    bool removeMember(const char* key);

private:
    Document m_jsonDocument;
};

#endif

MyJson.cpp

#include "MyJson.h"
#include <stdio.h>
#include "rapidjson/filereadstream.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
MyJson::MyJson(void)
{
    if (!m_jsonDocument.IsObject())
    {
        m_jsonDocument.SetObject();
    }
}

MyJson::~MyJson(void)
{

}
bool MyJson::readFile(const char* fileName)
{
    if (fileName == nullptr)
    {
        cout << "The FileName can't be Null!" << endl;
        return false;
    }

    FILE* pFile;
    fopen_s(&pFile, fileName, "rb");
    if (pFile == nullptr)
    {
        cout << "The FileName = " << fileName <<  " can't be read or opened !" << endl;
        return false;
    }

    char* pBuffer;
    fseek(pFile, 0, SEEK_END);
    size_t nLength = ftell(pFile);
    pBuffer = new char[nLength + 1];
    rewind(pFile);
    fread(pBuffer, sizeof(char), nLength, pFile);
    pBuffer[nLength] = 0;
    fclose(pFile);

    //std::cout << "Read: The File content is:" << pBuffer << std::endl;

    m_jsonDocument.Parse(pBuffer);

    return true;
}

void MyJson::addValueMember(const char* key, Value& object)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    strKey.SetString(key, allocator);
    m_jsonDocument.AddMember(strKey, object, allocator);
}

void MyJson::addValueMember(Value& object1, const char* key, Value& object2)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    strKey.SetString(key, allocator);
    object1.AddMember(strKey, object2, allocator);
}

void MyJson::addStrMember(const char* key, const char* value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strValue(kStringType);
    Value strKey(kStringType);
    strKey.SetString(key, allocator);
    strValue.SetString(value, allocator);
    m_jsonDocument.AddMember(strKey, strValue, allocator);
}

void MyJson::addStrValue(Value& object, const char* key, const char* value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();
    Value strKey(kStringType);
    Value strValue(kStringType);
    strKey.SetString(key, allocator);
    strValue.SetString(value, allocator);
    object.AddMember(strKey, strValue, allocator);
}

void MyJson::addIntMember(const char* key, int value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    Value nValue(kNumberType);
    strKey.SetString(key, allocator);
    nValue.SetInt(value);
    m_jsonDocument.AddMember(strKey, nValue, allocator);
}

void MyJson::addIntValue(Value& object, const char* key, int value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();
    Value strKey(kStringType);
    Value nValue(kNumberType);
    strKey.SetString(key, allocator);
    nValue.SetInt(value);
    object.AddMember(strKey, nValue, allocator);
}

void MyJson::addFloatMember(const char* key, float value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    Value fValue(kNumberType);
    strKey.SetString(key, allocator);
    fValue.SetFloat(value);
    m_jsonDocument.AddMember(strKey, fValue, allocator);
}

void MyJson::addFloatValue(Value& object, const char* key, float value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    Value fValue(kNumberType);
    strKey.SetString(key, allocator);
    fValue.SetFloat(value);
    object.AddMember(strKey, fValue, allocator);
}

void MyJson::addDoubleMember(const char* key, double value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();

    Value strKey(kStringType);
    Value dValue(kNumberType);
    strKey.SetString(key, allocator);
    dValue.SetDouble(value);
    m_jsonDocument.AddMember(strKey, dValue, allocator);
}

void MyJson::addDoubleValue(Value& object, const char* key, double value)
{
    Document::AllocatorType& allocator = m_jsonDocument.GetAllocator();
    Value strKey(kStringType);
    Value dValue(kNumberType);
    strKey.SetString(key, allocator);
    dValue.SetDouble(value);
    object.AddMember(strKey, dValue, allocator);
}

bool MyJson::hasMember(const char* key)
{
    if (m_jsonDocument.HasMember(key)) 
    {
        return true;
    }

    return false;
}

bool MyJson::removeMember(const char* key)
{
    if (!m_jsonDocument.HasMember(key)) 
    {
        return true;
    }

    return m_jsonDocument.RemoveMember(key);
}

bool MyJson::writeFile(const char* fileName)
{
    if (fileName == nullptr)
    {
        return false;
    }

    //转为字符串格式
    StringBuffer buffer;
    //PrettyWriter是格式化的json,如果是Writer则是换行空格压缩后的json
    PrettyWriter<StringBuffer> pretty_writer(buffer);  //Writer<StringBuffer> writer(buffer);
    pretty_writer.SetMaxDecimalPlaces(2);
    m_jsonDocument.Accept(pretty_writer);
    const char* pBuffer = buffer.GetString();

    //std::cout << "Write: The File content is:" << pBuffer << std::endl;

    FILE* pFile;
    fopen_s(&pFile, fileName, "wb");

    if (!pFile)
    {
        cout << "The FileName = " << fileName << " can't be opened !" << endl;
        return false;
    }
    fwrite(pBuffer, sizeof(char), strlen(pBuffer), pFile);
    fclose(pFile);

    return true;
}

4、自己写了一个测试例子

int main(int argv, char* argc[])
{
    MyJson pJson;

    Value url_objects(kObjectType);
    Value price_objects(kObjectType);
    Value info_objects(kObjectType);

    //pJson.addStrMember("name", rapidjson::StringRef(data_in["name"].c_str()), allocator);
    pJson.addStrMember("id", "1");
    pJson.addStrMember("name", "ZLY");
    

    pJson.addStrValue(url_objects,"success_url", "http://www.url.com");
    pJson.addStrValue(url_objects,"cannel_url", "http://www.ur2.com");
    pJson.addValueMember("urls", url_objects);

    pJson.addStrValue(info_objects, "desc", "description");
    pJson.addStrValue(info_objects, "date", "2020-07-16");
    pJson.addFloatValue(price_objects, "amount", 9.8);
    pJson.addStrValue(price_objects, "currency", "CNY");
    pJson.addValueMember(info_objects, "price" ,price_objects);

    pJson.addValueMember("info", info_objects);

    pJson.writeFile("person.json");

    return 0;
}

person.json内容如下:

{
	"id": "1",
	"name" : "ZLY",
	"urls" : {
    			"success_url": "http://www.url.com",
       			 "cannel_url" : "http://www.ur2.com"
			 },
    "info" : {
        		"desc": "description",
           		"date" : "2020-07-16",
            	"price" : {
	            			"amount": 9.8,
                			"currency" : "CNY"
       					  }
    		 }
}
 类似资料: