02rapidJson学习之数组的创建、遍历
概述:
创建数组时我们需要注意以下内容:
1)不能直接返回数组,我试过不行,因为数组必须依赖某一对象.即若我们不将数组添加到doc上,而直接返回数组是不行的。
1 数组的创建
//从doc中获取string字符串内容
std::string GetStrWithDoc(Document &doc){
rapidjson::StringBuffer buffer;//画板
rapidjson::Writer<StringBuffer> writer(buffer);//画家交给画板
doc.Accept(writer);//利用画家将doc的内容画进画板
return buffer.GetString();
}
/*
在doc中创建数组.
注:不能直接返回数组,我试过不行,因为数组必须依赖某一对象.
即若我们不将数组添加到doc上,而直接返回数组是不行的.
*/
void RapidCreateArr(Document &doc){
//1 设置对象和获取分配器,防止组装json格式出错
doc.SetObject();
Document::AllocatorType& a = doc.GetAllocator();
//2 创建数组,必须声明枚举为数组类型
Value a1(kArrayType);
//3 这里简单循环添加int,一般数组里面都是循环添加多个对象
for(auto i = 0; i < 5; i++){
a1.PushBack(i, a);
}
//可以连续创建,因为返回的是引用
a1.PushBack("C++11", a).PushBack("C++14", a);
//4 必须将数组绑定到某一对象返回,这里是doc
doc.AddMember("data", a1, a);
}
//在doc创建数组
void test02(){
rapidjson::Document doc;
RapidCreateArr(doc);
std::string str= GetStrWithDoc(doc);
std::cout<< str <<std::endl;
}
执行上面程序结果如下:
2 数组的遍历
数组的遍历有三种,第一种是利用内部SizeType(实际为uint)类型的下标;第二种是利用迭代器;第三种是利用C++11新特性auto。创建数组的函数RapidCreateArr上面已经有了,所以下面不再拷贝了。
1)SizeType下标遍历。
//数组的遍历-下标
void test03(){
rapidjson::Document doc;
RapidCreateArr(doc);
//利用上面的函数创建数组后,就可以进行遍历
//1 先判断data成员是否存在并且要求为数组类型
if(!(doc.HasMember("data") && doc["data"].IsArray())){
std::cout << "数组data不存在或者data不是数组类型" << std::endl;
return;
}
//2 开始遍历
const Value &a1 = doc["data"];//先获取数组
for(SizeType i = 0; i < a1.Size(); i++){
if(a1[i].IsInt()){
//一般这里会再与自己的数据比较然后作业务处理
std::cout << a1[i].GetInt() << " ";
}
else if(a1[i].IsString()){
std::cout << a1[i].GetString() <<" ";
}else{
//其它类型按照这样判断即可
}
}
std::cout<<std::endl;
}
2)迭代器的遍历。
//数组的遍历-迭代器
void test04(){
rapidjson::Document doc;
RapidCreateArr(doc);
//利用上面的函数创建数组后,就可以进行遍历
//1 先判断data成员是否存在并且要求为数组类型
if(!(doc.HasMember("data") && doc["data"].IsArray())){
std::cout << "数组data不存在或者data不是数组类型" << std::endl;
return;
}
//2 开始遍历
const Value &a1 = doc["data"];//先获取数组
//Value::ConstValueIterator为通用Value类型的迭代器
for (Value::ConstValueIterator it = a1.Begin(); it != a1.End(); it++){
if(it->IsInt()){
std::cout << it->GetInt()<< " ";
}else if(it->IsString()){
std::cout << it->GetString() << " ";
}else{
//
}
}
std::cout<<std::endl;
}
3)C++11新特性。
//数组的遍历-C++11新特性
void test05(){
rapidjson::Document doc;
RapidCreateArr(doc);
//利用上面的函数创建数组后,就可以进行遍历
//1 先判断data成员是否存在并且要求为数组类型
if(!(doc.HasMember("data") && doc["data"].IsArray())){
std::cout << "数组data不存在或者data不是数组类型" << std::endl;
return;
}
//2 开始遍历
const Value &a1 = doc["data"];//先获取数组
//x的值为a数组依次的元素,注意x必须获取的是引用,这就是rapid高效的地方,基本不支持拷贝赋值
for(auto &x:a1.GetArray()){
if(x.IsInt()){
std::cout << x.GetInt()<< " ";
}else if(x.IsString()){
std::cout << x.GetString() << " ";
}else{
//
}
}
std::cout<<std::endl;
}
主函数很简单,顺便也列一下吧。
int main(){
//test01();
//test02();
//test03();
//test04();
test05();
return 0;
}
上面3种遍历后的结果都是一样的:
搞定rapidjson的数组创建,很简单,容易出错的地方在rapidjson第一节初始化已经总结了。我们创建数组只需要注意上面的概述即可,即不能直接返回数组。
下一节将讲述kObjectType的创建与遍历。