rapidjson常见使用示例

前端之家收集整理的这篇文章主要介绍了rapidjson常见使用示例前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

rapidjson相比jsoncpp性能高出太多,使用接口一样的简单的。官方中文帮助文档:http://rapidjson.org/zh-cn/


rapidjson的Move语意,请浏览http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html#MoveSemantics
示例:
rapidjson::Value a(123);
rapidjson::Value b(456);
b = a; // a变成Null,b变成数字123,这样的做法是基于性能考虑


除了上述示例的复制语句外,AddMember()和PushBack()也采用了Move语意。


深复制Value:
Value v1("foo");
// Value v2(v1); // 不容许
Value v2(v1,a); // 制造一个克隆,v1不变


Document d;
v2.CopyFrom(d,a); // 把整个document复制至v2,d不变


rapidjson为了最大化性能,大量使用了浅拷贝,使用之前一定要了解清楚。
如果采用了浅拷贝,特别要注意局部对象的使用,以防止对象已被析构了,却还在被使用。


  1. // 需要#include的头文件
  2. #include <rapidjson/document.h>
  3. #include <rapidjson/error/en.h> // en为english的简写,定义了取出错信息的函数GetParseError_En(errcode)
  4. #include <rapidjson/stringbuffer.h>
  5. #include <rapidjson/writer.h>
  6.  
  7. // 示例1:解析一个字符串
  8. // 运行输出结果:
  9. // count=2
  10. // name=zhangsan
  11. // name=wangwu
  12. void x1()
  13. {
  14. rapidjson::Document document; // 定义一个Document对象
  15. std::string str = "{\"count\":2,\"names\":[\"zhangsan\",\"wangwu\"]}";
  16.  
  17. document.Parse(str.c_str()); // 解析,Parse()无返回值,也不会抛异常
  18. if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
  19. {
  20. // 可通过GetParseError()取得出错代码
  21. // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
  22. // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明,这里的En为English简写
  23. // 函数GetErrorOffset()返回出错发生的位置
  24. printf("parse error: (%d:%d)%s\n",document.GetParseError(),document.GetErrorOffset(),rapidjson::GetParseError_En(document.GetParseError()));
  25. }
  26. else
  27. {
  28. // 判断某成员是否存在
  29. if (!document.HasMember("count") || !document.HasMember("names"))
  30. {
  31. printf("invalid format: %s\n",str.c_str());
  32. }
  33. else
  34. {
  35. // 如果count不存在,则运行程序会挂,DEBUG模式下直接abort
  36. rapidjson::Value& count_json = document["count"];
  37. // 如果count不是整数类型,调用也会挂,DEBUG模式下直接abort
  38. // GetInt()返回类型为int
  39. // GetUint()返回类型为unsigned int
  40. // GetInt64()返回类型为int64_t
  41. // GetUint64()返回类型为uint64_t
  42. // GetDouble()返回类型为double
  43. // GetString()返回类型为char*
  44. // GetBool()返回类型为bool
  45. int count = count_json.GetInt();
  46. printf("count=%d\n",count);
  47. // 方法GetType()返回枚举值: kNullType,kFalseType,kTrueType,kObjectType,kArrayType,kStringType,kNumberType
  48. // 可用IsArray()判断是否为数组,示例: { "a": [1,2,3,4] }
  49. // 用IsString()判断是否为字符串值
  50. // 用IsDouble()判断是否为double类型的值,示例: { "pi": 3.1416 }
  51. // 用IsInt()判断是否为int类型的值
  52. // 用IsUint()判断是否为unsigned int类型的值
  53. // 用IsInt64()判断是否为int64_t类型的值
  54. // 用IsUint64()判断是否为uint64_t类型的值
  55. // 用IsBool()判断是否为bool类型的值
  56. // 用IsFalse()判断值是否为false,示例: { "t": true,"f": false }
  57. // 用IsTrue()判断值是否为true
  58. // 用IsNull()判断值是否为NULL,示例: { "n": null }
  59. // 更多说明可浏览:
  60. // https://miloyip.gitbooks.io/rapidjson/content/zh-cn/doc/tutorial.zh-cn.html
  61.  
  62. const rapidjson::Value& names_json = document["names"];
  63. for (rapidjson::SizeType i=0; i<names_json.Size(); ++i)
  64. {
  65. std::string name = names_json[i].GetString();
  66. printf("name=%s\n",name.c_str());
  67. }
  68. }
  69. }
  70. }
  71.  
  72. // 示例2:构造一个json并转成字符串
  73. // 输出结果:
  74. // {"count":2,"names":[{"name":"zhangsan"},{"name":"wangwu"}]}
  75. void x2()
  76. {
  77. rapidjson::StringBuffer buffer;
  78. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  79.  
  80. writer.StartObject();
  81.  
  82. // count
  83. writer.Key("count");
  84. writer.Int(2);
  85. // 写4字节有符号整数: Int(int32_t x)
  86. // 写4字节无符号整数: Uint(uint32_t x)
  87. // 写8字节有符号整数: Int64(int64_t x)
  88. // 写8字节无符号整数: Uint64(uint64_t x)
  89. // 写double值: Double(double x)
  90. // 写bool值: Bool(bool x)
  91.  
  92. // names
  93. writer.Key("names");
  94. writer.StartArray();
  95.  
  96. writer.StartObject();
  97. writer.Key("name");
  98. writer.String("zhangsan");
  99. writer.EndObject();
  100.  
  101. writer.StartObject();
  102. writer.Key("name");
  103. writer.String("wangwu");
  104. writer.EndObject();
  105.  
  106. writer.EndArray();
  107. writer.EndObject();
  108.  
  109. // 以字符串形式打印输出
  110. printf("%s\n",buffer.GetString());
  111. }
  112.  
  113. // 示例3:修改一个已有的json字符串
  114. // 运行输出结果:
  115. // {"name":"wangwu","age":22}
  116. void x3()
  117. {
  118. rapidjson::Document document;
  119. std::string str = "{\"name\":\"zhangsan\",\"age\":20}";
  120. document.Parse(str.c_str());
  121.  
  122. rapidjson::Value& name_json = document["name"];
  123. rapidjson::Value& age_json = document["age"];
  124. std::string new_name = "wangwu";
  125. int new_age = 22;
  126.  
  127. // 注意第三个参数是document.GetAllocator(),相当于深拷贝,rapidjson会分配一块内存,然后复制new_name.c_str(),
  128. // 如果不指定第三个参数,则是浅拷贝,也就是rapidjson不会分配一块内存,而是直接指向new_name.c_str(),省去复制提升了性能
  129. // 官方说明:
  130. // http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html#CreateString
  131. name_json.SetString(new_name.c_str(),new_name.size(),document.GetAllocator());
  132. age_json.SetInt(new_age);
  133.  
  134. // 转成字符串输出
  135. rapidjson::StringBuffer buffer;
  136. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  137. document.Accept(writer);
  138. printf("%s\n",buffer.GetString());
  139. }
  140.  
  141. // 示例4:读数组
  142. // 运行输出结果:
  143. // zhangsan wangwu
  144. void x4()
  145. {
  146. rapidjson::Document document;
  147. std::string str = "{\"count\":2,\"names\":[{\"name\":\"zhangsan\"},{\"name\":\"wangwu\"}]}";
  148.  
  149. document.Parse(str.c_str());
  150. if (document.HasParseError())
  151. {
  152. printf("parse error: %d\n",document.GetParseError());
  153. }
  154. else
  155. {
  156. rapidjson::Value& names_json = document["names"];
  157. for (rapidjson::SizeType i=0; i<names_json.Size(); ++i)
  158. {
  159. if (names_json[i].HasMember("name"))
  160. {
  161. rapidjson::Value& name_json = names_json[i]["name"];
  162. printf("%s ",name_json.GetString());
  163. }
  164. }
  165. printf("\n");
  166. }
  167. }
  168.  
  169. // 示例5: 以Writer构造一个json,然后修改它,最后转成字符串
  170. // 运行输出结果:
  171. // {"count":2}
  172. // {"count":8}
  173. void x5()
  174. {
  175. rapidjson::StringBuffer buffer1;
  176. rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
  177. writer1.StartObject();
  178. writer1.Key("count");
  179. writer1.Int(2);
  180. writer1.EndObject();
  181. printf("%s\n",buffer1.GetString());
  182.  
  183. // 转成Document对象
  184. rapidjson::Document document;
  185. document.Parse(buffer1.GetString());
  186.  
  187. // 修改
  188. rapidjson::Value& count_json = document["count"];
  189. count_json.SetInt(8);
  190. // 转成字符串
  191. rapidjson::StringBuffer buffer2;
  192. rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);
  193.  
  194. document.Accept(writer2);
  195. printf("%s\n",buffer2.GetString());
  196. }
  197.  
  198. // 示例6: 以Document构造一个json,然后修改它,最后转成字符串
  199. // 运行输出结果:
  200. // {"count":3,"names":[{"id":1,"name":"zhangsan"}]}
  201. // {"count":9,"name":"zhangsan"}]}
  202. void x6()
  203. {
  204. rapidjson::Document document;
  205. std::string str = "{}"; // 这个是必须的,且不能为"",否则Parse出错
  206. document.Parse(str.c_str());
  207.  
  208. // 新增成员count
  209. document.AddMember("count",document.GetAllocator());
  210.  
  211. // 新增数组成员
  212. rapidjson::Value array(rapidjson::kArrayType);
  213. rapidjson::Value object(rapidjson::kObjectType); // 数组成员
  214. object.AddMember("id",1,document.GetAllocator());
  215. object.AddMember("name","zhangsan",document.GetAllocator());
  216. // 注意下面用法编译不过:
  217. //std::string str1 = "hello";
  218. //object.AddMember("name",str1.c_str(),document.GetAllocator());
  219. //const char* str2 = "hello";
  220. //object.AddMember("name",str2,document.GetAllocator());
  221. //
  222. // 下面这样可以:
  223. //object.AddMember("name","hello",document.GetAllocator());
  224. //const char str3[] = "hello";
  225. //object.AddMember("name",str3,document.GetAllocator());
  226. //
  227. //std::string str4 = "#####";
  228. //rapidjson::Value v(str4.c_str(),document.GetAllocator());
  229. //obj.AddMember("x",v,document.GetAllocator());
  230. // 上面两行也可以写在一行:
  231. //obj.AddMember("x",rapidjson::Value(str4.c_str(),document.GetAllocator()).Move(),document.GetAllocator());
  232.  
  233. // 添加到数组中
  234. array.PushBack(object,document.GetAllocator());
  235. // 添加到document中
  236. document.AddMember("names",array,document.GetAllocator());
  237.  
  238. // 转成字符串输出
  239. rapidjson::StringBuffer buffer1;
  240. rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
  241. document.Accept(writer1);
  242. printf("%s\n",buffer1.GetString());
  243. // 修改
  244. rapidjson::Value& count_json = document["count"];
  245. count_json.SetInt(9);
  246.  
  247. // 再次输出
  248. rapidjson::StringBuffer buffer2;
  249. rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);
  250. document.Accept(writer2);
  251. printf("%s\n",buffer2.GetString());
  252. }
  253.  
  254. // 不转义就输出
  255. // 示例7: 以Document构造一个json,然后修改它,最后转成字符串
  256. // 运行输出结果:
  257. // x7=>
  258. // {"title":"\u8D2B\u56F0\u5B64\u513F\u52A9\u517B"}
  259. void x7()
  260. {
  261. std::string root = "{}";
  262. rapidjson::Document document;
  263. document.Parse(root.c_str());
  264.  
  265. std::string title = "\u8D2B\u56F0\u5B64\u513F\u52A9\u517B";
  266. document.AddMember("title",rapidjson::Value(title.c_str(),document.GetAllocator());
  267.  
  268. rapidjson::StringBuffer buffer;
  269. rapidjson::Writer<rapidjson::StringBuffer,rapidjson::Document::EncodingType,rapidjson::ASCII<> > writer(buffer);
  270. // 如果上面一句改成普通的:
  271. // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  272. // 则输出将变成:
  273. // x7=>
  274. // 贫困孤儿助养
  275. document.Accept(writer);
  276. printf("x7=>\n%s\n",buffer.GetString());
  277. }
  278.  
  279. // 示例8:构造空对象和数组
  280. // 运行输出结果:
  281. // {"age":{},"times":{},"names":[],"urls":[],"books":[]}
  282. // {"age":6,"books":[]}
  283. void x8()
  284. {
  285. rapidjson::Document document;
  286. document.Parse("{}"); // 这里换成document.SetObject()也可以
  287.  
  288. // 下面为2种构造空对象的方法
  289. document.AddMember("age",rapidjson::Value(rapidjson::kObjectType).Move(),document.GetAllocator());
  290. document.AddMember("times",rapidjson::Value().SetObject(),document.GetAllocator());
  291.  
  292. // 下面为2种构造空数组的方法
  293. document.AddMember("names",rapidjson::Value(rapidjson::kArrayType).Move(),document.GetAllocator());
  294. document.AddMember("urls",document.GetAllocator());
  295. document.AddMember("books",rapidjson::Value().SetArray(),document.GetAllocator());
  296.  
  297. rapidjson::StringBuffer buffer1;
  298. rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
  299. document.Accept(writer1);
  300. printf("%s\n",buffer1.GetString());
  301.  
  302. rapidjson::Value& age = document["age"];
  303. age.SetInt(6);
  304.  
  305. rapidjson::StringBuffer buffer2;
  306. rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);
  307. document.Accept(writer2);
  308. printf("%s\n",buffer2.GetString());
  309. }
  310.  
  311. int main()
  312. {
  313. x1();
  314. x2();
  315. x3();
  316. x4();
  317. x5();
  318. x6();
  319. x7();
  320. x8();
  321. return 0;
  322. }
  323.  
  324. // 示例:不转义中文
  325. // 运行输出结果:
  326. //{"title":"贫困孤儿助养"}
  327. //{"title":"\u8D2B\u56F0\u5B64\u513F\u52A9\u517B"}
  328. //g++ -g -o b b.cpp -I/usr/local/thirdparty/rapidjson/include
  329. #include <rapidjson/document.h>
  330. #include <rapidjson/stringbuffer.h>
  331. #include <rapidjson/writer.h>
  332. #include <string>
  333. #include <stdio.h>
  334.  
  335. int main()
  336. {
  337. std::string str = "{\"title\":\"\u8d2b\u56f0\u5b64\u513f\u52a9\u517b\"}";
  338. rapidjson::Document document;
  339. document.Parse(str.c_str());
  340. if (document.HasParseError())
  341. {
  342. printf("parse %s Failed\n",str.c_str());
  343. exit(1);
  344. }
  345.  
  346. rapidjson::StringBuffer buffer1;
  347. rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
  348. document.Accept(writer1);
  349. printf("%s\n",buffer1.GetString());
  350.  
  351. rapidjson::StringBuffer buffer2;
  352. rapidjson::Writer<rapidjson::StringBuffer,rapidjson::ASCII<> > writer2(buffer2);
  353. document.Accept(writer2);
  354. printf("%s\n",buffer2.GetString());
  355.  
  356. return 0;
  357. }
  358.  
  359. // 辅助函数:任意类型都以字符串返回,
  360. // 如果不存在,或者为数组则返回空字符串。
  361. std::string rapidjson_string_value(rapidjson::Value& value,const std::string& name)
  362. {
  363. if (!value.HasMember(name.c_str()))
  364. return std::string("");
  365.  
  366. const rapidjson::Value& child = value[name.c_str()];
  367. if (child.IsString())
  368. return child.GetString();
  369.  
  370. char str[100];
  371. if (child.IsInt())
  372. {
  373. snprintf(str,sizeof(str),"%d",child.GetInt());
  374. }
  375. else if (child.IsInt64())
  376. {
  377. // 为使用PRId64,需要#include <inttypes.h>,
  378. // 同时编译时需要定义宏__STDC_FORMAT_MACROS
  379. snprintf(str,"%"PRId64,child.GetInt64());
  380. }
  381. else if (child.IsUint())
  382. {
  383. snprintf(str,"%u",child.GetUint());
  384. }
  385. else if (child.IsUint64())
  386. {
  387. snprintf(str,"%"PRIu64,child.GetUint64());
  388. }
  389. else if (child.IsDouble())
  390. {
  391. snprintf(str,"%.2lf",child.GetDouble());
  392. }
  393. else if (child.IsBool())
  394. {
  395. if (child.IsTrue())
  396. strcpy(str,"true");
  397. else
  398. strcpy(str,"false");
  399. }
  400. else
  401. {
  402. str[0] = '\0';
  403. }
  404.  
  405. return str;
  406. }
  407.  
  408. // 辅助函数
  409. // 当为int32_t值,或字符串实际为int32_t值时,返回对应的int32_t值,其它情况返回0
  410. int32_t rapidjson_int32_value(rapidjson::Value& value,const std::string& name)
  411. {
  412. if (!value.HasMember(name.c_str()))
  413. return 0;
  414.  
  415. const rapidjson::Value& child = value[name.c_str()];
  416. if (child.IsInt())
  417. {
  418. return child.GetInt();
  419. }
  420. else if (child.IsString())
  421. {
  422. return atoi(child.GetString());
  423. }
  424.  
  425. return 0;
  426. }
  427.  
  428. // 辅助函数
  429. // 当为int64_t值,或字符串实际为int64_t值时,返回对应的int64_t值,其它情况返回0
  430. int64_t rapidjson_int64_value(rapidjson::Value& value,const std::string& name)
  431. {
  432. if (!value.HasMember(name.c_str()))
  433. return 0;
  434.  
  435. const rapidjson::Value& child = value[name.c_str()];
  436. if (child.IsInt64())
  437. {
  438. return child.GetInt64();
  439. }
  440. else if (child.IsString())
  441. {
  442. return (int64_t)atoll(child.GetString());
  443. }
  444.  
  445. return 0;
  446. }
  447.  
  448. // 辅助函数
  449. // 当为uin32_t值,或字符串实际为uin32_t值时,返回对应的uin32_t值,其它情况返回0
  450. uint32_t rapidjson_uint32_value(rapidjson::Value& value,const std::string& name)
  451. {
  452. if (!value.HasMember(name.c_str()))
  453. return 0;
  454.  
  455. const rapidjson::Value& child = value[name.c_str()];
  456. if (child.IsUint())
  457. {
  458. return child.GetUint();
  459. }
  460. else if (child.IsString())
  461. {
  462. return (uint32_t)atoll(child.GetString());
  463. }
  464.  
  465. return 0;
  466. }
  467.  
  468. // 辅助函数
  469. // 当为uin64_t值,或字符串实际为uin64_t值时,返回对应的uin64_t值,其它情况返回0
  470. uint64_t rapidjson_uint64_value(rapidjson::Value& value,const std::string& name)
  471. {
  472. if (!value.HasMember(name.c_str()))
  473. return 0;
  474.  
  475. const rapidjson::Value& child = value[name.c_str()];
  476. if (child.IsUint64())
  477. {
  478. return child.GetUint64();
  479. }
  480. else if (child.IsString())
  481. {
  482. return (uint64_t)atoll(child.GetString());
  483. }
  484.  
  485. return 0;
  486. }

猜你在找的Json相关文章