RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库,综合性能是最好的。
1. 安装
在NuGet中为项目安装tencent.rapidjson
2. 引用头文件
#include <rapidjson/document.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/prettywriter.h>
3. 头文件定义
添加测试json字符串和类型对应数组
// 测试json字符串
const char* strJson = "{\"name\":\"MenAngel\",\"age\":23,\"hobbys\":[\"语文\",\"数学\",\"英语\",54],\"scores\":{\"数学\":\"90.6\",\"英语\":\"100.0\", \"语文\":\"80.0\"}}";
// 数据类型,和 rapidjson的enum Type 相对应
static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
4. 修改JSON 内容
/// <summary>
/// 修改JSON 内容
/// </summary>
void MyRapidJson::alterJson()
{
rapidjson::Document doc;
doc.Parse(strJson);
cout << "修改前: " << strJson <<"\n" << endl;
// 修改内容
rapidjson::Value::MemberIterator iter = doc.FindMember("name");
if (iter != doc.MemberEnd())
doc["name"] = "张三";
iter = doc.FindMember("age");
if (iter != doc.MemberEnd())
{
rapidjson::Value& v1 = iter->value;
v1 = "40";
}
// 修改后的内容写入 StringBuffer 中
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
doc.Accept(writer);
cout <<"修改后: " << buffer.GetString() << "\n" << endl;
}
运行结果:
{"name":"张三","age":"40","hobbys":["语文","数学","英语",54],"scores":{"数学":"90.6","英语":"100.0","语文":"80.0"}}
5. 生成 json 数据
/// <summary>
/// 生成JSON数据
/// </summary>
void MyRapidJson::createJson()
{
// 1.准备数据
string name = "王五";
string gender = "boy";
int age = 23;
bool student = true;
vector<string> hobbys = { "语文","数学","英语" };
map<string, double> scores = { {"语文",80},{"数学",90},{"英语",100} };
//2.初始化DOM
rapidjson::Document doc;
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
doc.SetObject();
// 添加数据
/* 字符串添加 */
rapidjson::Value tempValue1;
tempValue1.SetString(name.c_str(), allocator);
doc.AddMember("name", tempValue1, allocator);
rapidjson::Value tempValue2(rapidjson::kStringType);
tempValue2.SetString(gender.c_str(), allocator);
doc.AddMember(rapidjson::StringRef("gender"), tempValue2, allocator);
/* 数字类型添加 */
doc.AddMember("age", age, allocator);
/* bool 类型 */
rapidjson::Value tempValueStu(rapidjson::kTrueType);
tempValueStu.SetBool(student);
doc.AddMember(rapidjson::StringRef("student"), tempValueStu, allocator);
/* Array 添加数据 */
rapidjson::Value tempValue3(rapidjson::kArrayType);
for (auto hobby : hobbys)
{
rapidjson::Value hobbyValue(rapidjson::kStringType);
hobbyValue.SetString(hobby.c_str(), allocator);
tempValue3.PushBack(hobbyValue, allocator);
}
doc.AddMember("hobbys", tempValue3, allocator);
/* Object 添加 */
rapidjson::Value tempValue4(rapidjson::kObjectType);
tempValue4.SetObject();
for (auto score : scores)
{
//rapidjson::Value scoreName(rapidjson::kStringType);
//scoreName.SetString(score.first.c_str(), allocator);
//tempValue4.AddMember(scoreName, score.second, allocator);
// 方法二
rapidjson::Value scoreName(rapidjson::kStringType);
scoreName.SetString(score.first.c_str(), allocator);
rapidjson::Value scoreValue(rapidjson::kStringType);
char charValue[20];
itoa(score.second, charValue,10);
scoreValue.SetString(charValue, allocator);
tempValue4.AddMember(scoreName, scoreValue, allocator);
}
doc.AddMember("scores", tempValue4, allocator);
// 写入 StringBuffer
rapidjson::StringBuffer strBuffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(strBuffer);
doc.Accept(writer);
cout << strBuffer.GetString() << "\n" << endl;
string outFileName = "C:\\Users\\Administrator\\Desktop\\creatJson.txt";
ofstream outfile(outFileName, std::ios::trunc);
outfile << strBuffer.GetString() << endl;
outfile.flush();
outfile.close();
}
运行结果:
{"name":"王五","gender":"boy","age":23,"student":true,"hobbys":["语文","数学","英语"],"scores":{"数学":"90","英语":"100","语文":"80"}}
6. json 数据解析
/// <summary>
/// 查询json 内容
/// </summary>
void MyRapidJson::searchJson()
{
rapidjson::Document doc;
if (doc.Parse(strJson).HasParseError())
{
std::cout << "json 解析错误" << std::endl;
return;
}
cout << "doc 的属性成员有 " << doc.MemberCount() << "个!" << endl;
vector<string> propertyName;
int i = 0;
for (rapidjson::Value::MemberIterator iter = doc.MemberBegin(); iter != doc.MemberEnd(); ++iter)
{
cout << ++i << "、 " << iter->name.GetString() << " is " << kTypeNames[iter->value.GetType()] << endl;
propertyName.push_back(iter->name.GetString());
}
cout << endl;
for (rapidjson::Value::MemberIterator iter = doc.MemberBegin(); iter != doc.MemberEnd(); ++iter)
{
if (iter->value.GetType() == rapidjson::kObjectType || iter->value.GetType() == rapidjson::kArrayType)
cout << iter->name.GetString() << " : " << endl;
else
cout << iter->name.GetString() << " : ";
DfsDocument(std::move(iter->value));
}
}
/// <summary>
/// 遍历里面的内容
/// </summary>
/// <param name="val"></param>
void MyRapidJson::DfsDocument(rapidjson::Value val)
{
if (!val.GetType())
return;
switch (val.GetType()) {
case rapidjson::kNumberType:
cout << val.GetInt() << endl;
break;
case rapidjson::kStringType:
cout << val.GetString() << endl;
break;
case rapidjson::kArrayType:
for (rapidjson::Value::ValueIterator itr = val.GetArray().begin();
itr != val.GetArray().end(); ++itr) {
rapidjson::Value a;
a = *itr;
DfsDocument(std::move(a));
}
break;
case rapidjson::kObjectType:
for (rapidjson::Value::MemberIterator itr = val.GetObject().begin();
itr != val.GetObject().end(); ++itr) {
cout << itr->name.GetString() << " ";
rapidjson::Value a;
a = itr->value;
DfsDocument(std::move(a));
}
default:
break;
}
}
运行结果
这里需要注意:
object 类型json字符串中,“数字类型” 需转为 “字符串”,否则查询时会报错。
7. rapidjson 的其他使用方法
/// <summary>
/// json 属性
/// </summary>
void MyRapidJson::JsonAttribute()
{
rapidjson::Document doc;
if (doc.Parse(strJson).HasParseError())
{
std::cout << "json 解析错误" << std::endl;
return;
}
// 成员判断
if (doc.HasMember("hobbys") && !doc["hobbys"].Empty())
cout << "doc[\"hobbys\"] is not empty!" << "\n" << endl;
else
cout << "doc[\"hobbys\"] 不存在。" << "\n" << endl;
//7.Array的大小
if (doc["hobbys"].IsArray())
{
cout << "doc[\"hobbys\"].Capacity() = \" Array的容量及大小:\" " << doc["hobbys"].Capacity() << " 项" << endl;
cout << "doc[\"hobbys\"].Size() = \" Array的容量及大小:\" " << doc["hobbys"].Size() << " 项" << endl;
}
// 字符串长度获取
cout << doc["name"].GetString() <<" 字符串长度 :" << doc["name"].GetStringLength() << endl;
//4.查询某个成员是否存在
rapidjson::Value::MemberIterator iter = doc.FindMember("scores");
if (iter != doc.MemberEnd())
{
cout << iter->name.GetString() << " : " << endl;
DfsDocument(std::move(iter->value));
}
else
cout << "Not Finded!" << endl;
// 相同判断
if (doc["name"].GetString() == string("MenAngel") &&
doc["name"] == "MenAngel" &&
strcmp(doc["name"].GetString(),"MenAngel") == 0)
{
cout << "判断为相等" << endl;
}
}
运行结果: