Cocos2d-X网络编程(5) 使用Rapidjson解析数据

Json基础及28种c++解析库性能对比

JSON 概念和特点:
    JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
    JSON 是轻量级的文本数据交换格式,类似 XML,但比 XML 更小、更快,更易解析
    JSON 独立于语言 *
    JSON 具有自我描述性,更易理解  。
 
JSON的创建方式与创建 JavaScript 对象的代码相同。
Json的格式:
{
    "project_type": "javascript",
    "debugMode" : 1,
    "showFPS" : true,
    "frameRate" : 60,
    "id" : "gameCanvas",
    "renderMode" : 0,
    "engineDir":"frameworks/cocos2d-html5",
    "modules" : ["cocos2d", "extensions"],
    "jsList" : [
        "src/loader/loaderRes.js",
        "src/loader/loaderScene.js"
    ]
}
 
JSON 值可以是:
       数字(整数或浮点数)
       字符串(在双引号中)
       逻辑值(true 或 false)
       数组(在方括号中)
       对象(在花括号中)
       null。
JSON 是 JavaScript 原生格式。JavaScript可以直接使用JSON,不需要调用api或工具包。
由于JSON的易用性,其他语言也提供了强大的JSON 解析器和 JSON 库。c++语音有28种json库。下面的图表是对28种json库的评估:
符合标准程度(越高越好):

解析至DOM的时间(越低越好):

把DOM生成含换行及缩进的JSON的时间(越低越好):

可执行文件(把JSON解析至DOM,然后统计JSON类型)的大小(越低越好):

 


1:使用Rapidjson解析字符串成json格式数据


1、创建一个rapidjson::Document对象rapidJson的相关操作都在Document类中
   rapidjson::Document
2、调用Parse方法解析json数据
   doc.Parse<0>(data.c_str());
3、使用HasParseError()判断解析出来的document是否正确。解析正确才能做进一步操作。
 

2:使用Rapidjson读取和更改数据

在rapidJson中,使用rapidjson::Value代表json数据中的值。rapidjson::Value其实就是js中的var,可以把rapidjson::Value当作int,也可以当作string,也可以当作数组等。对于定义rapidjson::Value value,只是一个定义,还没有决定其数据类型,如果明确value的类型,再转成相应的格式。Value的类型包括int,Double,string,bool,array,obejct,null。


json使用key-value的方式,读取数据时使用脚标的方式:rapidjson::Value  &value=doc["hello"];

在获取脚本之前,还可以使用HasMember方法判断是否有这个键值对

然后判断value的类型:value.IsString()判断是否是字符串,IsArray()判断是否是数组等
判断好数据的类型后,可以调用对应的方法获取c/c++数据类型。比如如果value是字符串,则可以通过getString方法获取字符串的值。
并且可以通过SetString方法修改该value的值。
除了修改value的值,也可以修改value的类型,通过set+类型的方法设置,有下面这些方法可以设置value的值。
vall.SetArray()
vall.SetArrayRaw()
vall.SetBool()
vall.SetDouble()
vall.SetInt()
vall.SetNull()
vall.SetObject()
vall.SetString()
vall.SetStringRaw()
vall.SetUint();
vall.SetUint64()

 

3:把json数据转成字符串

使用rapidjson::Writer 把 rapidjson::Value 转成符合json数据格式的字符串:
先声明一个rapidjson::StringBuffer类型的数据
    rapidjson::StringBuffer  buffer;
再创建一个rapidjson::Writer对象
    rapidjson::Writer<rapidjson::StringBuffer>  writer(buffer);
    doc.Accept(writer); 
然后就可以通过buffer.GetString()获取c/c++的字符串了。
 
 

4:使用Rapidjson添加、删除数据

Rapidjson除了能够读取和修改数据,还能添加和删除数据。
添加数据时,先获取一个分配器
  rapidjson::Document::AllocatorType  &allocator = doc.GetAllocator();
添加一个数:
doc.AddMember("age",15,allocator);
添加一个字符串:
doc.AddMember("name","liao li",allocator);
///添加一个null对象
rapidjson::Value nullObject(rapidjson::kNullType);
doc.AddMember("null",nullObject,allocator);///<往分配器中添加一个对象
添加一个对象:
rapidjson::Value  object(rapidjson::kObjectType);///<创建数组里面对象。
object.AddMember("age",40,allocator);
object.AddMember("name","father ",allocator);
doc.AddMember("father",object,allocator);
///添加一个数组对象
rapidjson::Value  array(rapidjson::kArrayType);///<创建一个数组对象
array.PushBack(1,allocator);
array.PushBack(2,allocator);
array.PushBack(3,allocator);
doc.AddMember("array",array,allocator)
///在已有的数组中添加一个成员对象
rapidjson::Value  &aArray1=doc["array"];
aArray1.PushBack(4,allocator);
 


代码实操:

直接修改前面http的代码

#include "TestRapidJson.h"
#include "cocos2d\external\json\rapidjson.h"
#include "cocos2d\external\json\document.h"
#include "cocos2d\external\json\stringbuffer.h"
#include "cocos2d\external\json\writer.h"

Scene* TestRapidJson::createScene()
{
    auto scene = Scene::create();
    auto layer = TestRapidJson::create();
    scene->addChild(layer);
    return scene;
}

bool TestRapidJson::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
	//post 
	auto postReq = new HttpRequest();
	postReq->setTag("type post");
	postReq->setUrl("http://httpbin.org/post");
	postReq->setRequestType(HttpRequest::Type::POST);
	std::vector<std::string> header;
	header.push_back("Content-Type:application/json;charset=utf-8");
	postReq->setHeaders(header);
	const char* reqData = "response Data";
	postReq->setRequestData(reqData,strlen(reqData));
	postReq->setResponseCallback(CC_CALLBACK_2(TestRapidJson::complete,this));

	auto client2 = HttpClient::getInstance();
	client2->send(postReq);
	postReq->release();

    return true;
}
void TestRapidJson::complete(HttpClient *client,HttpResponse *response)
{
	log("request tag is:%s",response->getHttpRequest()->getTag());
	log("response code is:%d",response->getResponseCode());
	if(response->isSucceed())
	{
		/*std::vector<char> * data = response->getResponseData();
		log("response data is:");
		for (int i = 0; i < data->size(); i++)
		{
			log("%c",(*data)[i]);
		}*/
		std::vector<char> * data = response->getResponseData();
		std::stringstream oss;
		for (int i = 0; i < data->size(); i++)
		{
			oss<<(*data)[i];
		}
		std::string str = oss.str();
		log("response data is:%s",str.c_str());

		// 1:创建一个rapidjson::Document对象
		rapidjson::Document doc;
		// 1:调用Parse方法解析json数据
		doc.Parse<0>(str.c_str());
		// 1:判断解析是否成功
		if (doc.HasParseError())
		{
			log("json parse error : %s",doc.GetParseError());
		}else//解析成功之后的操作
		{
			log("parse success");
			// 2:判断类型,判断是否有该数据
			if (doc.IsObject()&&doc.HasMember("data"))
			{
				// 2:读取值
				rapidjson::Value &value = doc["data"];
				if (value.IsString())
				{
					// 2:获取值
					log("data is :%s",value.GetString());
				}
			}

			if (doc.IsObject()&&doc.HasMember("json"))
			{
				// 2:设置值
				doc["json"].SetInt(15);
				log("json is :% d",doc["json"].GetInt()	);
			}

			// 3:声明一个rapidjson::StringBuffer类型的数据
			rapidjson::StringBuffer buffer;
			// 3:创建一个rapidjson::Writer对象
			rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
			doc.Accept(writer);
			// 3:获取c/c++的字符串
			log("json string is: %s",buffer.GetString());

			// 4:获取一个分配器
			rapidjson::Document::AllocatorType &allocator=doc.GetAllocator();
			//添加整数
			doc.AddMember("int",20,allocator);

			//添加字符串
			doc.AddMember("string","string value",allocator);
			//添加一个null对象
			rapidjson::Value nullObj(rapidjson::kNullType);
			doc.AddMember("null",nullObj,allocator);
			//添加了一个对象
			rapidjson::Value obj(rapidjson::kObjectType);
			obj.AddMember("name","xiaoli",allocator);
			obj.AddMember("age",20,allocator);
			obj.AddMember("height",180,allocator);

			doc.AddMember("personInfo",obj,allocator);

			//添加一个数组
			rapidjson::Value arr(rapidjson::kArrayType);

			arr.PushBack(1,allocator);
			arr.PushBack("string in array",allocator);

			rapidjson::Value obj1(rapidjson::kObjectType);
			obj1.AddMember("name","xiaoli",allocator);
			obj1.AddMember("age",20,allocator);
			obj1.AddMember("height",180,allocator);

			arr.PushBack(obj1,allocator);
			
			doc.AddMember("arr",arr,allocator);

			rapidjson::StringBuffer buffer1;
			rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
			doc.Accept(writer1);
			log("modified data is: %s",buffer1.GetString());

		}
	}else
	{
		log("error msg is:%s",response->getErrorBuffer());
	}
}


 
 

 


 
 
 

 

posted @ 2018-09-01 12:43  穆玄琅  阅读(480)  评论(0编辑  收藏  举报