Rapidjson的簡單使用示例



很早就想用用Markdown了,一直沒機會。今天就來試一下

先放個目錄:


rapidjson官方教程

如果要想深入學習rapidjson工具,官方文檔肯定是必須看一看的。官方教程裏面的講解纔是最詳細,最權威的了。


本示例所用環境

  • 引擎版本:cocos2d-x 3.10

示例代碼與註釋

說明:我是直接使用原版引擎創建了新的cocos2dx工程,然後略微修改了HelloWorldScene.cpp中的代碼。爲了方便,使用rapidjson生成json串、保存json串到文件、從文件讀取json串、使用rapidjson解析json串的過程,全部寫到了initSelf()函數中。

本身很反感blog全篇粘代碼的方式(關鍵貼的代碼誰都看不懂,一行註釋沒有),但是這部分代碼示例沒有什麼可說的,所以在重點部分寫了註釋。

HelloWorldScene.h文件內容

#include "cocos2d.h"
class HelloWorld : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    CREATE_FUNC(HelloWorld);
private:
    void initSelf();
};

HelloWorldScene.cpp文件內容

#include "HelloWorldScene.h"

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

USING_NS_CC;

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

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    else {
        this->initSelf();
        return true;
    }
}

//重點
void HelloWorld::initSelf()
{
//生成一串如下的json格式字符串,並解析
// {
// "name":"qfl",
// "age":20,
// "letter":["a","b","c"],
// "location": {"province":"fujian","city":"xiamen","number":16}
// "book":[{"name":"book1", "isbn":"123"},{"name":"book2","isbn":"456"}],
// "healthy":true,
// }

    //生成Json串
    rapidjson::Document jsonDoc;    //生成一個dom元素Document
    rapidjson::Document::AllocatorType &allocator = jsonDoc.GetAllocator(); //獲取分配器
    jsonDoc.SetObject();    //將當前的Document設置爲一個object,也就是說,整個Document是一個Object類型的dom元素

    //添加屬性
    jsonDoc.AddMember("name", "qfl", allocator);    //添加字符串值
    jsonDoc.AddMember("age", 20, allocator);        //添加int類型值

    //生成array
    rapidjson::Value letterArray(rapidjson::kArrayType);//創建一個Array類型的元素
    letterArray.PushBack("a", allocator);
    letterArray.PushBack("b", allocator);
    letterArray.PushBack("c", allocator);
    jsonDoc.AddMember("letter", letterArray, allocator);    //添加數組

    //生成一個object
    rapidjson::Value locationObj(rapidjson::kObjectType);//創建一個Object類型的元素
    locationObj.AddMember("province", "fujian", allocator);
    locationObj.AddMember("city", "xiamen", allocator);
    locationObj.AddMember("number", 16, allocator);
    jsonDoc.AddMember("location", locationObj, allocator);  //添加object到Document中

    //生成一個object數組
    rapidjson::Value bookArray(rapidjson::kArrayType);//生成一個Array類型的元素,用來存放Object
    rapidjson::Value book1(rapidjson::kObjectType); //生成book1
    book1.AddMember("name", "book1", allocator);
    book1.AddMember("isbn", "123", allocator);
    bookArray.PushBack(book1, allocator);           //添加到數組

    rapidjson::Value book2(rapidjson::kObjectType); //生成book2
    book2.AddMember("name", "book2", allocator);
    book2.AddMember("isbn", "456", allocator);
    bookArray.PushBack(book2, allocator);           //添加到數組
    jsonDoc.AddMember("book", bookArray, allocator);

    //添加屬性
    jsonDoc.AddMember("healthy", true, allocator);  //添加bool類型值
// jsonDoc.AddMember("sports", NULL, allocator);//添加空值,這裏會導致報錯

    //生成字符串
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    jsonDoc.Accept(writer);

    std::string strJson = buffer.GetString();
    log("-----生成的Json:\n%s", strJson.c_str());

    //寫到文件
    std::string strPath = FileUtils::getInstance()->getWritablePath() + "JsonFile.txt";
    FILE* myFile = fopen(strPath.c_str(), "w");  //windows平臺要使用wb
    if (myFile) {
        fputs(buffer.GetString(), myFile);
        fclose(myFile);
    }

    //JsonFile.txt文件內容
    //{"name":"qfl","age":20,"letter":["a","b","c"],"location":{"province":"fujian","city":"xiamen","number":16},"book":[{"name":"book1","isbn":"123"},{"name":"book2","isbn":"456"}],"healthy":true}

    log("-----讀取Json內容:");
    //從文件中讀取(注意和上面分開,不能確定文件是否生成完畢,這裏讀取可能有問題)
    rapidjson::Document newDoc;
    myFile = fopen(strPath.c_str(), "r");   //windows平臺使用rb
    if (myFile) {
        rapidjson::FileStream inputStream(myFile);  //創建一個輸入流
        newDoc.ParseStream<0>(inputStream); //將讀取的內容轉換爲dom元素
        fclose(myFile); //關閉文件,很重要
    }
    //判斷解析從流中讀取的字符串是否有錯誤
    if (newDoc.HasParseError()) {
        log("Json Parse error:%d", newDoc.GetParseError()); //打印錯誤編號
    }
    else {
        //獲取json串中的數據
        //先判斷是否有這個字段,如果使用不存在的key去取值會導致直接崩潰
        if (newDoc.HasMember("name")) {
            log("name:%s", newDoc["name"].GetString()); //必須要獲取對應的數據類型,rapidjson不會幫你轉換類型
        }
        else {}

        if (newDoc.HasMember("age")) {
            log("age:%d", newDoc["age"].GetInt());  //獲取正確的類型
        }
        else {}

        if (newDoc.HasMember("letter")) {
            rapidjson::Value letter;    //使用一個新的rapidjson::Value來存放array的內容
            letter = newDoc["letter"];

            //確保它是一個Array,而且有內容
            if (letter.IsArray() && !letter.Empty()) {
                //遍歷Array中的內容
                for (rapidjson::SizeType i = 0; i < letter.Size(); i++) {
                    log("letter:%s", letter[i].GetString());
                }
            }
            else {}
        }
        else {}

        if (newDoc.HasMember("location")) {
            rapidjson::Value location;      //使用一個新的rapidjson::Value來存放object
            location = newDoc["location"];

            //確保它是一個Object
            if (location.IsObject()) {

                if (location.HasMember("province")) {
                    log("location:province:%s", location["province"].GetString());
                }
                else {}
                if (location.HasMember("city")) {
                    log("location:city:%s", location["city"].GetString());
                }
                else {}
                if (location.HasMember("number")) {
                    log("location:number:%d", location["number"].GetInt());
                }
                else {}
            }
            else {}
        }
        else {}

        //book是一個包含了2個object的array。按照上面的步驟來取值就行
        if (newDoc.HasMember("book")) {
            rapidjson::Value book;
            book = newDoc["book"];

            //先取Array
            if (book.IsArray() && !book.Empty()) {

                rapidjson::Value tempBook;
                for (rapidjson::SizeType i = 0; i < book.Size(); i++) {
                    tempBook = book[i]; //Array中每個元素又是一個Object

                    if (tempBook.IsObject()) {

                        if (tempBook.HasMember("name") && tempBook.HasMember("isbn")) {
                            log("book:%d:name:%s, isbn:%s", i, tempBook["name"].GetString(), tempBook["isbn"].GetString());
                        }
                        else {}
                    }
                    else {}
                }
            }
            else {}
        }
        else {}

        if (newDoc.HasMember("healthy")) {
            if (newDoc["healthy"].GetBool()) {
                log("healthy:true");
            }
            else {
                log("healthy:false");
            }
        }
        else {}
    }
}
發佈了152 篇原創文章 · 獲贊 157 · 訪問量 103萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章