2RapidJson的详解及使用

    本节主要介绍RapidJson是如何使用的。

 

  (1)RapidJson是什么

RapidJson是一个跨平台的c++的json的解析器和生成器; 相比较jsoncpp库,RapidJson只有头文件,容易安装; RapidJSON 不依赖STL和boost等外部库独立; 只使用如下文件:<cstdio>,<cstdlib>,<cstring>,<inttypes.h>,<new>,<stdint.h>;
高性能,使用模版及内联函数去降低函数调用开销、内部经优化的 Grisu2 及浮点数解析实现、可选的 SSE2/SSE4.2 支持.

 

  (2)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() //SetDouble() //SetFloat() //SetArray() //SetObject() //SetNull() //3.将DOM stringfy 为json StringBuffer buffer; Writer<StringBuffer> writer(buffer); doc.Accept(writer); cout<< buffer.GetString() << endl; return 0; }
{"key1":"value1","key2":"value2","key3":100} {"key1":"value1","key2":"value_modify","key3":101}

 

  (3)文件对象模型(Document Object Model,DOM)API

    文件对象模型,在RapidJson中广泛的使用。

    1.构建json value到DOM:

#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.准备数据
  string name = "MenAngel"; string gender = "boy"; int age = 23; vector<string> hobbys = {"语文","数学","英语"}; map<string,double> score ={{"语文",80},{"数学",90},{"英语",100}}; // 2.初始化DOM
 StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); //2.1 根DOM开始
 writer.StartObject(); writer.Key("name"); writer.String(name.c_str()); writer.Key("gender"); writer.String(gender.c_str());
writer.Key("age");
writer.Int(age); writer.Key(
"hobby"); writer.StartArray(); for(auto &item : hobbys) { writer.String(item.c_str()); } writer.EndArray(); writer.Key("scores"); writer.StartObject(); for(auto &item : scores) { writer.Key((item.first).c_str()); writer.Double(item.second); } writer.EndObject(); //2.2 根DOM结束 writer.EndObject(); //3.将上述DOM组织的json数据写入json.txt文件 string outFileName = "json.txt"; ofstream outfile(outFileName,std::ios::trunc); outfile<<strBuffer.GetString()<<endl; outfile.flush(); outfile.close(); return 0; }
{"name":"MenAngel","gender":"boy","age":23,"hobbys":["语文","英语"],"scores":{"数学":90.0,"英语":100.0,"语文":80.0}}

    2.构建Json Value到DOM

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

using namespace std; using namespace rapidjson; int main(int argv,double> scores ={{"语文",100}}; //2.初始化DOM
 Document doc; Document::AllocatorType& allocator = doc.GetAllocator(); doc.SetObject();//实例化一个GenericValue到根DOM
 Value tempValue1; tempValue1.SetString(name.c_str(),allocator); doc.AddMember("name",tempValue1,allocator); Value tempValue2(rapidjson::kObjectType); tempValue2.SetString(gender.c_str(),allocator); doc.AddMember("gender",tempValue2,allocator); doc.AddMember("age",age,allocator); Value tempValue3(kArrayType); for(auto hobby:hobbys) { Value hobbyValue(kStringType); hobbyValue.SetString(hobby.c_str(),allocator); tempValue3.PushBack(hobbyValue,allocator); } doc.AddMember("hobbys",tempValue3,allocator); Value tempValue4(kObjectType); tempValue4.SetObject(); for(auto score : scores) { Value scoreValue(kNumberType); //cout<<score.second;
 scoreValue.SetInt(score.second); Value scoreName(kStringType); scoreName.SetString(score.first.c_str(),allocator); tempValue4.AddMember(scoreName,scoreValue,allocator); } doc.AddMember("scores",tempValue4,allocator); StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); doc.Accept(writer); string outFileName = "json.txt"; ofstream outfile(outFileName,"age":23,"hobbys":["语文","语文":80.0}}

    3.RapidJSon查询

#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
  const char * strJson = "{\"name\":\"MenAngel\",\"age\":23,\"hobbys\":[\"语文\",\"数学\",\"英语\"]}"; Document doc; doc.Parse(strJson); StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); doc.Accept(writer); cout<<strBuffer.GetString()<<endl; //2.查询json值
  cout<<"遍历方法一:"<<endl; int count = doc.MemberCount(); cout<<"doc 的属性成员有 "<<count<<"个!"<<endl; static const char* kTypeNames[] = { "Null","False","True","Object","Array","String","Number" }; int i = 0; for(Value::MemberIterator iter = doc.MemberBegin();iter != doc.MemberEnd();++iter) { cout<<++i<<".property "<<iter->name.GetString()<<" is "<<kTypeNames[iter->value.GetType()]<<endl; if(iter->value.GetType() == 4) { //3.遍历Array
      for(auto &item : iter->value.GetArray()) //IsBool、IsObject、IsInt、IsNull、IsNumber、IsDouble
        if(item.IsString()) cout<<"item = "<<item.GetString()<<endl; } } //4.查询某个成员是否存在
  Value::ConstMemberIterator it = doc.FindMember("scores"); if(it != doc.MemberEnd()) cout<<"Has Finded!"<<endl; else cout<<"Not Finded!"<<endl; //5.遍历doc的所有成员
  cout<<"遍历方法二:"<<endl; for(auto &m :doc.GetObject()) { cout<<"Has member :"<<m.name.GetString()<<" = "; if(m.value.IsString()) cout<<m.value.GetString()<<endl; if(m.value.IsInt()) cout<<m.value.GetInt()<<endl; if(m.value.IsBool()) cout<<m.value.GetBool()<<endl; if(m.value.IsArray()) cout<<"is array"<<endl; } return 0; }
{"name":"MenAngel","英语"]} 遍历方法一: doc 的属性成员有 3个!
1.property name is String 2.property age is Number 3.property hobbys is Array item = 语文 item = 数学 item = 英语 Not Finded! 遍历方法二: Has member :name = MenAngel Has member :age = 23 Has member :hobbys = is array

    4.RapidJson属性获取

#include <iostream> #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h"
using namespace std; using namespace rapidjson; int main(int argv,\"英语\"]}"; Document doc; doc.Parse(strJson); StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); doc.Accept(writer); cout<<strBuffer.GetString()<<endl; //2.DOM根是一个对象
  if(doc.IsObject()) cout<<"doc is object!"<<endl; //3.doc不为j空
  if(!doc.IsNull()) { cout<<"doc is not null!"<<endl; } Document document; if(document.IsNull()) { cout<<"document is null!"<<endl; cout<<"Set Object"<<endl; document.SetObject(); } if(!document.IsNull()) cout<<"document is not null!"<<endl; //4.DOM 的大小.
  cout<<"doc.MemmberCount() = "<<doc.MemberCount()<<endl; //5.增加HasMember判断防止断言错误
  if(doc.HasMember("hobbys") && !doc["hobbys"].Empty()) cout<<"doc[\"hobbys\"] is not empty!"<<endl; else cout<<"member not exits!"<<endl; //6.取键值
  Value::ConstMemberIterator iter = doc.FindMember("age"); if(iter != doc.MemberEnd()) { cout<<"Member age is exits!"<<endl; cout<<iter->name.GetString()<<":"<<iter->value.GetInt()<<endl; } //7.Array的大小
  cout<<"doc[\"hobbys\"].Capacity() = "<<doc["hobbys"].Capacity()<<endl; //8.字符串的大小 当字符中存在\u0000时strlen会到此截断
  cout<<"doc[\"name\"].length = "<<strlen(doc["name"].GetString())<<endl; cout<<"doc[\"name\"].length = "<<doc["name"].GetStringLength()<<endl; doc.AddMember("test","a\u0000b",doc.GetAllocator()); //只能当test成员存在时才能直接赋值 //doc["test"] = "a\u0000b";
  cout<<"doc[\"test\"].length = "<<strlen(doc["test"].GetString())<<endl; cout<<"doc[\"test\"].length = "<<doc["test"].GetStringLength()<<endl; //   return 0; }
{"name":"MenAngel","英语"]} doc is object! doc is not null! document is null! Set Object document is not null! doc.MemmberCount() = 3 doc["hobbys"] is not empty! Member age is exits! age:23 doc["hobbys"].Capacity() = 3 doc["name"].length = 8 doc["name"].length = 8 doc["test"].length = 1 doc["test"].length = 3

    5.RapidJson一些特性

#include <iostream> #include <stdio.h> #include <stdlib.h> #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h"
using namespace std; using namespace rapidjson; int main(int argv,\"英语\"]}"; Document doc; doc.Parse(strJson); StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); doc.Accept(writer); cout<<strBuffer.GetString()<<endl; //2.const char *、string、value(kStringType)之间比较大小
  if(doc["name"] == "MenAngel") cout<<"(1)doc[\"name\"] equal MenAngel!"<<endl; if(doc["name"].GetString() == string("MenAngel")) cout<<"(2)doc[\"name\"] equal MenAngel!"<<endl; if( 0 == strcmp(doc["name"].GetString(),"MenAngel")) cout<<"(3)doc[\"name\"] equal MenAngel!"<<endl; if(doc["name"].GetString() != "MenAngel") cout<<"(4)不成立!"<<endl; //3.value赋值
  Value v;//v is NULL && v is not Object
  if(v.IsNull()) cout<<"v is Null()"<<endl; v.SetObject(); if(v.IsObject()) cout<<"v is Object"<<endl; Value tValue(kObjectType);//tValue is not Null,tValue is Object
  if(!tValue.IsNull()) cout<<"tVlaue is not NULL!"<<endl; if(tValue.IsObject()) cout<<"tValue is Object"<<endl; //4.转移语义,避免value深赋值 //AddMember(),PushBack()、赋值均采用深赋值
  Value a(123); Value b(456); a = b; if(b.IsNull()) cout<<"b is Null,"<<"a = "<<a.GetInt()<<endl; Value c(kArrayType); Document::AllocatorType& allocator = doc.GetAllocator(); c.PushBack(Value(11),allocator); c.PushBack(Value().SetInt(22),allocator); // fluent API
  c.PushBack(Value(33).Move(),allocator);   // 转移语义
  cout<<"c.Capacity() = "<<c.Capacity()<<endl; cout<<"c.Size() = "<<c.Size()<<endl; for(auto &m : c.GetArray()) { cout<<"item = "<<m.GetInt()<<endl; } //字符串的容量及大小
  cout<<"doc[\"hobbys\"].Size() = "<<doc["hobbys"].Size()<<endl; cout<<"doc[\"hobbys\"].Capacity() = "<<doc["hobbys"].Capacity()<<endl; //5.交换value
  Value d(123); Value e("string"); d.Swap(e); if(!d.IsNull() && !e.IsNull()) { cout<<"d is not null,e is not null!"<<endl; cout<<"d = "<<d.GetString()<<" e = "<<e.GetInt()<<endl; } //6.创建string //复制字符串
 Value f(kStringType); char str[20] = "My first string!"; f.SetString(str,doc.GetAllocator()); cout<<f.GetString()<<endl; Value g; char buffer[20]; int len = sprintf(buffer,"%s -> %s","name","value"); // 动态创建的字符串。
 g.SetString(buffer,len,doc.GetAllocator()); //g.SetString(buffer,doc.GetAllocator())
  cout<<g.GetString()<<endl; //简单引用常量字符串
 Value h; h.SetString("My third String!");// h = "My thrid String!"
  cout<<h.GetString()<<endl; //简单引用常量l字符串
 Value i; const char * tempStr = "my fourth string"; size_t cstr_len = strlen(tempStr); i.SetString(StringRef(tempStr)); //i.SetString(StringRef(tempStr,cstr_len)); //i = StringRef(tempStr,cstr_len) //i = StringRef(tempStr) //i.SetString(tempStr); 不合法
  cout<<i.GetString()<<endl; return 0; }
{"name":"MenAngel","英语"]} (1)doc["name"] equal MenAngel! (2)doc["name"] equal MenAngel! (3)doc["name"] equal MenAngel! (4)不成立! v is Null() v is Object tVlaue is not NULL! tValue is Object b is Null,a = 456 c.Capacity() = 16 c.Size() = 3 item = 11 item = 22 item = 33 doc["hobbys"].Size() = 3 doc["hobbys"].Capacity() = 3 d is not null,e is not null! d = string e = 123 My first string! name -> value My third String! my fourth string

相关文章

文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览...
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 j...
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口...
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列...
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_uni...