rapidjson实战


前言

RapidJSON 是一个小、快、独立的 C++ 的 JSON 解析器及生成器,仅由头文件组成。具备如下特点:

  • 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”(空字符)。

资源参见:

  1. rapidjson API 网站
  2. rapidjson github 仓库

一、应用

序列化步骤

  1. 创建rapidjson::StringBuffer strBuf实例
  2. 用创建的rapidjson::StringBuffer实例初始化rapidjson::Writer, 如rapidjson::Writerrapidjson::StringBuffer
  3. wirter(strBuf) writer.StartObject()
  4. writer.Key() wirter.Int() …
  5. writer.EndObject()

解析步骤

  1. 创建文档解析对象 rapidjson::Document doc
  2. 判断是否存在解析错误 if(!doc.Parse(str.data()).HasParseError())
  3. 判断待解析字段是否存在 if(doc.HasMember(“Persions”) && doc[“Persions”].IsArray())
  4. 将字段转换成rapidjson::Value引用类型 const rapidjson::Value& array = doc[“Persions”];
  5. 对每一个字段进行解析 如有嵌套的类型应该将嵌套类型转换为rapidjson::Value引用类型后再解析,详见代码

实战

#include"rapidjson/document.h"
#include"rapidjson/stringbuffer.h"
#include"rapidjson/writer.h"

#include<vector>
#include<stdio.h>
#include<string>

//定义一个结构体 并提供无参构造函数和有参数构造函数 提供init函数
struct Persion {
  std::string name;
  int age;
  std::string team;

  Persion(){

  }

  Persion(std::string p_name, int p_age, std::string p_team){
    name = p_name;
    age = p_age;
    team =p_team;
  }

  void init(std::string p_name, int p_age, std::string p_team){
    name = p_name;
    age = p_age;
    team = p_team;
  }

};

std::string serialize_persion_vector(std::vector<Persion> vec){
  rapidjson::StringBuffer strBuf;
  rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);

  writer.StartObject();
  writer.Key("Persions");
  writer.StartArray();

  std::vector<Persion>::iterator it;
  for(it = vec.begin(); it != vec.end(); it++)
  {
    writer.StartObject();
    writer.Key("name");
    writer.String((*it).name.c_str());
    writer.Key("age");
    writer.Int((*it).age);
    writer.Key("team");
    writer.String((*it).team.c_str());
    writer.EndObject();
  }

  writer.EndArray();
  writer.EndObject();
  
  std::string data = strBuf.GetString();
  return data;

}

std::vector<Persion> parse_persion_vector(std::string str){
  std::vector<Persion> vec;
  //创建文档解析对象
  rapidjson::Document doc;
  //首先进行解析,如过没有解析错误,才能进入下一步具体字段解析
  if(!doc.Parse(str.data()).HasParseError())
  {
    if(doc.HasMember("Persions") && doc["Persions"].IsArray()){
        //将字段转换成rapidjson::Value引用类型
      const rapidjson::Value& array = doc["Persions"];
      size_t len = array.Size();
      for(int i = 0; i < len; ++i)
      { 
        //将嵌套的字段转换成rapidjson::Value引用类型
        const rapidjson::Value& item = array[i];
        struct Persion persion;
        
        //对每一个字段进行解析
        if(item.HasMember("name") && item["name"].IsString()){
          persion.name = item["name"].GetString();
        }else{
          printf("no name\n");
        }

        if(item.HasMember("age") && item["age"].IsInt()){
          persion.age = item["age"].GetInt();
        }else{
          printf("no age\n");
        }

        if(item.HasMember("team") && item["team"].IsString()){
          persion.team = item["team"].GetString();
        }else{
          printf("no team\n");
        }

        vec.push_back(persion);
      }
    }
  }else{
    printf("parse error\n");
  }

  printf("vec.size():%d\n", (int)vec.size());
  return vec;

}


int main(){
  struct Persion persion1, persion2;
  persion1.init("James", 33, "Lakers");
  persion2.init("Paul", 34, "Rockets");
  
  std::vector<Persion> persion_vec;
  persion_vec.push_back(persion1);
  persion_vec.push_back(persion2);

  //序列号一个内容为persion 结构体类型的verctor
  std::string persion_vector_str = serialize_persion_vector(persion_vec);
  printf("persion_vector_str:%s\n", persion_vector_str.c_str());

  //用序列化的结果进行反序列化  验证整个过程是否正确
  std::vector<Persion> persion_vec2 = parse_persion_vector(persion_vector_str);
  std::string persion_vector_str2 = serialize_persion_vector(persion_vec2);

  printf("persion_vector_str2:%s\n", persion_vector_str2.c_str());
  return 0;
}

注意事项

  • rapidjson相关函数均为单词首字母大写
  • 需要解析的字段必须转换为rapidjson::Value&类型,注意是引用
  • 本实例包含c++语法,编译时使用g++命令
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值