rapidjson 入门-1

////////////////////////////////////////////////////////////////////////////

//1. Parse a JSON text string to a document.

const char json[] =

"{"

"\"name\": \"Obama\","

"\"null\": null,"

"\"int\": 6,"

"\"double\": 3.14,"

"\"bool\": true,"

"\"array\": [5,6,7,8]"

"}";

/**

*json的数据类型有numberStringnullboolObjectarray

number可以是任何类型数字,数组的成员也可以是任何类型。由于c++

的限制,我们会在解析器中扩展出numberintunsigned int,double,等等

他们都属于number.

json的键只可以是String。不管什么类型的数据,亦或是键,他们都属于value类型

*/

Document document;

document.Parse(json);//解析

assert(!document.HasParseError());//查看是否有创建错误

//遍历表

for (auto b =document.MemberBegin(); b != document.MemberEnd(); ++b)

{

std::cout <<b->name.GetString()<<" ";//键依然是value类型

std::cout <<b->value.IsArray()<<b->value.IsNumber()<<b->value.IsString()<<b->value.IsBool();//可以发现json的值都保存在Value

}

std::cout <<std::endl;

/************************************************************************/

/* 跟节点的数据类型

早期的json版本,根节点数据只可以是数组或者Object,不过在最新版的json

中,支持所有类型作为根节点

*/

/************************************************************************/

assert(document.IsObject());

//assert(document.IsArray());导致断言

/************************************************************************/

/*索引值

支持下标和find操作

下标强制返回value的引用,find 返回键值对的迭代器

auto & ref =document["name"];

auto iter =document.findMember("name");

*/

/************************************************************************/

auto& ref = document["name"];//强制引用

auto iter =document.FindMember("name");

std::cout <<ref.GetString()<<std::endl;

std::cout << iter->name.GetString() <<iter->value.GetString();//迭代了键值对,name是一个固定String类型的value

std::cout <<std::endl;

/************************************************************************/

/* 获取值

可以用value::get***函数来获取value的具体值

*/

/************************************************************************/

/************************************************************************/

/* 判断值

Value::is***函数来判断具体类型

*/

/************************************************************************/

/************************************************************************/

/*

设定值

Value::set***可以设定修改某个键的值,值的类型可以变.

document也是一个Value

document在建立之初,我们可以为之设定一个初始值

document.SetObject();

*/

/************************************************************************/

auto& dou =document["double"];

dou.SetString("3.14");

/************************************************************************/

/* 遍历修改增加数组的值

*/

/************************************************************************/

auto& arr =document["array"];

for (auto b = arr.Begin(); b != arr.End(); ++b)//数组的成员依然是value,并且数据结构是Vector

{

std::cout<< b->GetInt();

}

for (int i = 0; i < arr.Size(); ++i)//既然是vector,那么就支持下标操作

{

arr[i].SetInt(6);

}

//插入弹出--popBack

arr.PushBack(8/*创建一个Value*/,document.GetAllocator());//显示传递内存分配器,一般标准库容器作为模板实参,其默认值都会失效

arr.PushBack(Value("啦啦啦"),document.GetAllocator());

//我们需要显式指定allocator

/************************************************************************/

/* 数字

数字在调用getdouble时候会发生自动转换。对于int,unsigned intdouble,可以无损转换

但是int64会使数据丢失*/

/************************************************************************/

std::cout <<std::endl;

/************************************************************************/

/* 比较

很幸运的是,value重载了== !=比较操作符,于是我们不必麻烦的用get函数之后再比较*/

/************************************************************************/

bool isS = ref =="Obama";//true

dou.SetDouble(3.14);

bool isD = dou != 3;

/************************************************************************/

/*Value的右值语意

对于value的赋值操作符 =

addMember

pushBack

他们的参数都是一个右值引用,于是,原来的值会被搬移到新的地方,而原来的值会变成null

对于现代的编译器,他们大多数都会有右值的优化,如果函数返回一个临时对象,外边还有人接受的话

那么就会由默认的右值语意,对于函数的形参也是一个道理。不过对于返回一个局部对象的话,这样必定会产生拷贝

在面对较大的拷贝时候,我们可以用std::move()函数显式的将局部对象转换成右值。

*/

/************************************************************************/

Valueo(kObjectType);

{

Valuecontacts(kArrayType);

//adding elements to contacts array.

o.AddMember("contacts",contacts,document.GetAllocator()); //Object添加成员

}

/************************************************************************/

/* String

*/

/************************************************************************/

Value v;

v.SetString("hello");//静态创建文本.默认调用strlen获得字符串长度

char buffer[10] ={0};

size_tlen = sprintf(buffer,"%s","hello");//动态文本

v.SetString(buffer,len);

//于是乎我们可以动态的创建一个document成员

document.AddMember(v,"啦啦啦啦啦啦啦",document.GetAllocator());

/************************************************************************/

/* 我需要深度拷贝

不能用=操作符,我如何拷贝?

*/

/************************************************************************/

{

Documentd;

Document::AllocatorType&a = d.GetAllocator();

Valuev1("foo");

//Value v2(v1); // not allowed

Value v2(v1,a); //构造拷贝

assert(v1.IsString()); // v1 untouched

d.SetArray().PushBack(v1,a).PushBack(v2,a); // 右值语意

assert(v1.IsNull()&& v2.IsNull());

v2.CopyFrom(d,a); // 构造拷贝第二种方法

assert(d.IsArray()&& d.Size() == 2); // d untouched

v1.SetObject().AddMember("array",v2,a);//右值语意

d.PushBack(v1,a);//右值语意

assert(v1.IsNull()&& v2.IsNull());

}

/************************************************************************/

/* 交换值*/

/************************************************************************/

{

Valueaa(123);

Valuebb("Hello");

aa.Swap(bb);

assert(aa.IsString());

assert(bb.IsInt());

}

相关文章

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