本文将介绍如何用rapidjson的DOM方式进行json的常见操作:
一、读取json数据
上代码:
const char json[] = " { \"hello\" : \"world\",\"t\" : true,\"f\" : false,\"n\": null,\"i\":123,\"pi\": 3.1416,\"a\":[1,2,3,4] } "; Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator. char buffer[sizeof(json)]; memcpy(buffer,json,sizeof(json)); if (document.ParseInsitu<0>(buffer).HasParseError()) { return 1; } printf("\nParsing to document succeeded.\n"); //////////////////////////////////////////////////////////////////////////// // 2. Access values in document. printf("\nAccess values in document:\n"); assert(document.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array. assert(document.HasMember("hello")); assert(document["hello"].IsString()); printf("hello = %s\n",document["hello"].GetString()); assert(document["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue(). printf("t = %s\n",document["t"].GetBool() ? "true" : "false"); assert(document["f"].IsBool()); printf("f = %s\n",document["f"].GetBool() ? "true" : "false"); printf("n = %s\n",document["n"].IsNull() ? "null" : "?"); assert(document["i"].IsNumber()); // Number is a JSON type,but C++ needs more specific type. assert(document["i"].IsInt()); // In this case,IsUint()/IsInt64()/IsUInt64() also return true. printf("i = %d\n",document["i"].GetInt()); // Alternative (int)document["i"] assert(document["pi"].IsNumber()); assert(document["pi"].IsDouble()); printf("pi = %g\n",document["pi"].GetDouble()); { const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster. assert(a.IsArray()); for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t. printf("a[%d] = %d\n",i,a[i].GetInt()); // Note: //int x = a[0].GetInt(); // Error: operator[ is ambiguous,as 0 also mean a null pointer of const char* type. int y = a[SizeType(0)].GetInt(); // Cast to SizeType will work. int z = a[0u].GetInt(); // This works too. } system("pause");
运行结果:
Parsing to document succeeded.
Access values in document:
hello = world
t = true
f = false
n = null
i = 123
pi = 3.1416
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
请按任意键继续. . .
二,构造json数据
Document变量被声明之后,要先调用SetObject方法
如果Document中没有某个字段,那么要先调用addmember增加这个字段,才可以往里面赋值
向array中增加字段时,要传入allocator
给某个字段赋予字符串时,有两种方式,一、只传入字符串的指针,二、将整个字符串拷贝一份进去
const char json[] = " { \"hello\" : \"world\",sizeof(json)); if (document.ParseInsitu<0>(buffer).HasParseError()) { return 1; } // Adding values to array. { Value& a = document["a"]; // This time we uses non-const reference. Document::AllocatorType& allocator = document.GetAllocator(); for (int i = 5; i <= 10; i++) a.PushBack(i,allocator); // May look a bit strange,allocator is needed for potentially realloc. We normally uses the document's. // Fluent API a.PushBack("Lua",allocator).PushBack("Mio",allocator); } // Making string values. // This version of SetString() just store the pointer to the string. // So it is for literal and string that exists within value's life-cycle. { document["hello"] = "rapidjson"; // This will invoke strlen() // Faster version: // document["hello"].SetString("rapidjson",9); } // This version of SetString() needs an allocator,which means it will allocate a new buffer and copy the the string into the buffer. Value author; { char buffer[10]; int len = sprintf(buffer,"%s %s","Milo","Yip"); // synthetic example of dynamically created string. author.SetString(buffer,len,document.GetAllocator()); // Shorter but slower version: // document["hello"].SetString(buffer,document.GetAllocator()); // Constructor version: // Value author(buffer,document.GetAllocator()); // Value author(buffer,document.GetAllocator()); memset(buffer,sizeof(buffer)); // For demonstration purpose. } // Variable 'buffer' is unusable now but 'author' has already made a copy. document.AddMember("author",author,document.GetAllocator()); assert(author.IsNull()); // Move semantic for assignment. After this variable is assigned as a member,the variable becomes null. //////////////////////////////////////////////////////////////////////////// // 4. Stringify JSON printf("\nModified JSON with reformatting:\n"); FileStream f(stdout); PrettyWriter<FileStream> writer(f); document.Accept(writer); // Accept() traverses the DOM and generates Handler events. system("pause");
三、导出json数据
需要调用document的Accept方法,传入一个Writer,Writer可以用文件流或者字符串来构造
导出json数据到文件,这里以导出到stdout为例
FileStream f(stdout); PrettyWriter<FileStream> writer(f); document.Accept(writer); // Accept() traverses the DOM and generates Handler events.
导出json数据到字符串,
StringBuffer strbuf; Writer<StringBuffer> writer(strbuf); document.Accept(writer);
这里的StringBuffer是rapidjson/stringbuffer.h中的类
完毕。。