rapidjson解析


 

json串轉成對象

cInfraredData* cInfraredData::to_obj(char* jsonstr) {
    cInfraredData* p = new cInfraredData();
    Document doc;
    doc.Parse(jsonstr);
    if (doc.HasMember("ipAddress")) {
        rapidjson::Value &val_ipAddress = doc["ipAddress"];
        if (val_ipAddress.IsString()) {
            p->ipAddress = val_ipAddress.GetString();
        }
    }
    if (doc.HasMember("dateTime")) {
        rapidjson::Value &val_dateTime = doc["dateTime"];
        if (val_dateTime.IsString()) {
            p->dateTime = val_dateTime.GetString();
        }
    }
    if (doc.HasMember("backgroundPic")) {
        rapidjson::Value &val_backgroundPic = doc["backgroundPic"];
        if (val_backgroundPic.IsString()) {
            p->backgroundPic = val_backgroundPic.GetString();
        }
    }    
    
    if (doc.HasMember("backgroundPicThermal")) {
        rapidjson::Value &val_backgroundPic = doc["backgroundPicThermal"];
        if (val_backgroundPic.IsString()) {
            p->backgroundPicThermal = val_backgroundPic.GetString();
        }
    }

    if (doc.HasMember("temperatureList") && doc["temperatureList"].IsArray()) {
        rapidjson::Value &list = doc["temperatureList"];
        for (unsigned int i = 0; i < list.Size(); i++) {
            const rapidjson::Value& object = list[i];
            if (object.IsObject()) {
                sAlarmVlPicAxis s={0,0,0,0,0.0};
                if (object.HasMember("alarmVlPicLeftTopX") && object["alarmVlPicLeftTopX"].IsInt())
                    s.alarmVlPicLeftTopX = object["alarmVlPicLeftTopX"].GetInt();
                if (object.HasMember("alarmVlPicLeftTopY") && object["alarmVlPicLeftTopY"].IsInt())
                    s.alarmVlPicLeftTopY = object["alarmVlPicLeftTopY"].GetInt();
                if (object.HasMember("alarmVlPicRightBottomX") && object["alarmVlPicRightBottomX"].IsInt())
                    s.alarmVlPicRightBottomX = object["alarmVlPicRightBottomX"].GetInt();
                if (object.HasMember("alarmVlPicRightBottomY") && object["alarmVlPicRightBottomY"].IsInt())
                    s.alarmVlPicRightBottomY = object["alarmVlPicRightBottomY"].GetInt();
                if (object.HasMember("temperature") && object["temperature"].IsFloat())
                    s.temperature = object["temperature"].GetFloat();
                p->temperatureList.push_back(s);
            }

        }
    }
    
    if (doc.HasMember("temperatureNormalList")) {
        rapidjson::Value &list = doc["temperatureNormalList"];
        if (list.IsArray()) {
            for (unsigned int i = 0; i < list.Size(); i++) {
                rapidjson::Value & val = list[i];
                if(val.IsBool())
                    p->temperatureNormalList.push_back(val.GetBool());
            }
        }
    }
    return p;
}

 

 

 

 

{
    "Int": 1, 
    "Double": 12.0000001, 
    "String": "This is a string", 
    "Object": {
        "name": "qq849635649", 
        "age": 25
    }, 
    "IntArray": [
        10, 
        20, 
        30
    ], 
    "DoubleArray": [
        1, 
        2, 
        3
    ], 
    "StringArray": [
        "one", 
        "two", 
        "three"
    ], 
    "MixedArray": [
        "one", 
        50, 
        false, 
        12.005
    ], 
    "People": [
        {
            "name": "qq849635649", 
            "age": 0, 
            "sex": true
        }, 
        {
            "name": "qq849635649", 
            "age": 10, 
            "sex": false
        }, 
        {
            "name": "qq849635649", 
            "age": 20, 
            "sex": true
        }
    ]
}

一、寫json協議

1. 下面這段代碼是我最喜歡用的一種方式,使用字符串緩沖器生成

#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <iostream>
#include <string>
 
using namespace std;
 
void Serialize_1()
{
    rapidjson::StringBuffer strBuf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
 
    writer.StartObject();
 
    //1. 整數類型
    writer.Key("Int");
    writer.Int(1);
 
    //2. 浮點類型
    writer.Key("Double");
    writer.Double(12.0000001);
 
    //3. 字符串類型
    writer.Key("String");
    writer.String("This is a string");
 
    //4. 結構體類型
    writer.Key("Object");
    writer.StartObject();
    writer.Key("name");
    writer.String("qq849635649");
    writer.Key("age");
    writer.Int(25);
    writer.EndObject();
 
    //5. 數組類型
    //5.1 整型數組
    writer.Key("IntArray");
    writer.StartArray();
    //順序寫入即可
    writer.Int(10);
    writer.Int(20);
    writer.Int(30);
    writer.EndArray();
 
    //5.2 浮點型數組
    writer.Key("DoubleArray");
    writer.StartArray();
    for(int i = 1; i < 4; i++)
    {
        writer.Double(i * 1.0);
    }
    writer.EndArray();
 
    //5.3 字符串數組
    writer.Key("StringArray");
    writer.StartArray();
    writer.String("one");
    writer.String("two");
    writer.String("three");
    writer.EndArray();
 
    //5.4 混合型數組
    //這說明了,一個json數組內容是不限制類型的
    writer.Key("MixedArray");
    writer.StartArray();
    writer.String("one");
    writer.Int(50);
    writer.Bool(false);
    writer.Double(12.005);
    writer.EndArray();
 
    //5.5 結構體數組
    writer.Key("People");
    writer.StartArray();
    for(int i = 0; i < 3; i++)
    {
        writer.StartObject();
        writer.Key("name");
        writer.String("qq849635649");
        writer.Key("age");
        writer.Int(i * 10);
        writer.Key("sex");
        writer.Bool((i % 2) == 0);
        writer.EndObject();
    }
    writer.EndArray();
 
    writer.EndObject();
 
    string data = strBuf.GetString();
    cout << data << endl;
}



2. 接下來這種方式是我剛開始學習使用該庫時網上收到的結果,使用不像上面那么方便
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
 
 
void Serialize_2()
{
    rapidjson::Document doc;
    doc.SetObject();
    rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
 
    //1. 整型類型
    doc.AddMember("Int", 1, allocator);
 
    //2. 浮點類型
    doc.AddMember("Double", 12.00001, allocator);
 
    //3. 字符串類型
    //正確方式
    string str= "This is a string";
    rapidjson::Value str_value(rapidjson::kStringType);
    str_value.SetString(str.c_str(), str.size());
    if(!str_value.IsNull())
    {
        doc.AddMember("String", str_value, allocator);
    }
    /**
     *    注:以下方式不正確,可能成功,也可能失敗,因為字符串寫入json要重新開辟內存,
     * 如果使用該方式的話,當數據是字符串常量的話是沒問題的,如果為變量就會顯示亂碼,所
     * 以為保險起見,我們顯式的分配內存(無需釋放)
     */
    //doc.AddMember("String", str.data(), allocator);
 
    //4. 結構體類型
    rapidjson::Value object(rapidjson::kObjectType);
    object.AddMember("name", "qq849635649", allocator); //注:常量是沒有問題的
    object.AddMember("age", 25, allocator);
    doc.AddMember("Object", object, allocator);
 
    //5. 數組類型
    //5.1 整型數組
    rapidjson::Value IntArray(rapidjson::kArrayType);
    IntArray.PushBack(10, allocator);
    IntArray.PushBack(20, allocator);
    IntArray.PushBack(30, allocator);
    doc.AddMember("IntArray", IntArray, allocator);
 
    //5.2 浮點型數組
    rapidjson::Value DoubleArray(rapidjson::kArrayType);
    DoubleArray.PushBack(1.0, allocator);
    DoubleArray.PushBack(2.0, allocator);
    DoubleArray.PushBack(3.0, allocator);
    doc.AddMember("DoubleArray", DoubleArray, allocator);
 
    //5.3 字符型數組
    rapidjson::Value StringArray(rapidjson::kArrayType);
    string strValue1 = "one";
    string strValue2 = "two";
    string strValue3 = "three";
    str_value.SetString(strValue1.c_str(), strValue1.size());
    StringArray.PushBack(str_value, allocator);
    str_value.SetString(strValue2.c_str(), strValue2.size());
    StringArray.PushBack(str_value, allocator);
    str_value.SetString(strValue3.c_str(), strValue3.size());
    StringArray.PushBack(str_value, allocator);
    doc.AddMember("StringArray", StringArray, allocator);
 
    //5.4 結構體數組
    rapidjson::Value ObjectArray(rapidjson::kArrayType);
    for(int i = 1; i < 4; i++)
    {
        rapidjson::Value obj(rapidjson::kObjectType);
        obj.AddMember("name", "qq849635649", allocator);//注:常量是沒有問題的
        obj.AddMember("age", i * 10, allocator);
        ObjectArray.PushBack(obj, allocator);
    }
    doc.AddMember("ObjectArray", ObjectArray, allocator);
 
    rapidjson::StringBuffer strBuf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
    doc.Accept(writer);
 
    string data = strBuf.GetString();
    cout << data << endl;
}

下面是解析的代碼,同樣的,采用的依舊上面那個json字符串,分門別類的已經整理好

#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
 
string data =
        "{\"Int\":1,"
        "\"Double\":12.0000001,"
        "\"String\":\"This is a string\","
        "\"Object\":{\"name\":\"qq849635649\",\"age\":25},"
        "\"IntArray\":[10,20,30],"
        "\"DoubleArray\":[1.0,2.0,3.0],"
        "\"StringArray\":[\"one\",\"two\",\"three\"],"
        "\"MixedArray\":[\"one\",50,false,12.005],"
        "\"People\":[{\"name\":\"qq849635649\",\"age\":0,\"sex\":true},"
        "{\"name\":\"qq849635649\",\"age\":10,\"sex\":false},"
        "{\"name\":\"qq849635649\",\"age\":20,\"sex\":true}]}";
 
void parse() {
    //創建解析對象
    rapidjson::Document doc;
    //首先進行解析,沒有解析錯誤才能進行具體字段的解析
    if(!doc.Parse(data.data()).HasParseError())
    {
        //1. 解析整數
        if(doc.HasMember("Int") && doc["Int"].IsInt())
        {
            cout << "Int = " << doc["Int"].GetInt() << endl;
        }
        //2. 解析浮點型
        if(doc.HasMember("Double") && doc["Double"].IsDouble())
        {
            cout << "Double = " << doc["Double"].GetDouble() << endl;
        }
        //3. 解析字符串
        if(doc.HasMember("String") && doc["String"].IsString())
        {
            cout << "String = " << doc["String"].GetString() << endl;
        }
        //4. 解析結構體
        if(doc.HasMember("Object") && doc["Object"].IsObject())
        {
            const rapidjson::Value& object = doc["Object"];
            if(object.HasMember("name") && object["name"].IsString())
            {
                cout << "Object.name = " << object["name"].GetString() << endl;
            }
            if(object.HasMember("age") && object["age"].IsInt())
            {
                cout << "Object.age = " << object["age"].GetInt() << endl;
            }
        }
        //5. 解析數組類型
        //5.1 整型數組類型
        if(doc.HasMember("IntArray") && doc["IntArray"].IsArray())
        {
            //5.1.1 將字段轉換成為rapidjson::Value類型
            const rapidjson::Value& array = doc["IntArray"];
            //5.1.2 獲取數組長度
            size_t len = array.Size();
            //5.1.3 根據下標遍歷,注意將元素轉換為相應類型,即需要調用GetInt()
            for(size_t i = 0; i < len; i++)
            {
                cout << "IntArray[" << i << "] = " << array[i].GetInt() << endl;
            }
        }
        //5.2 浮點型數組類型
        if(doc.HasMember("DoubleArray") && doc["DoubleArray"].IsArray())
        {
            const rapidjson::Value& array = doc["DoubleArray"];
            size_t len = array.Size();
            for(size_t i = 0; i < len; i++)
            {
                //為防止類型不匹配,一般會添加類型校驗
                if(array[i].IsDouble())
                {
                    cout << "DoubleArray[" << i << "] = " << array[i].GetDouble() << endl;
                }
            }
        }
        //5.3 字符串數組類型
        if(doc.HasMember("StringArray") && doc["StringArray"].IsArray())
        {
            const rapidjson::Value& array = doc["StringArray"];
            size_t len = array.Size();
            for(size_t i = 0; i < len; i++)
            {
                //為防止類型不匹配,一般會添加類型校驗
                if(array[i].IsString())
                {
                    cout << "StringArray[" << i << "] = " << array[i].GetString() << endl;
                }
            }
        }
        //5.4 混合型
        if(doc.HasMember("MixedArray") && doc["MixedArray"].IsArray())
        {
            const rapidjson::Value& array = doc["MixedArray"];
            size_t len = array.Size();
            for(size_t i = 0; i < len; i++)
            {
                //為防止類型不匹配,一般會添加類型校驗
                if(array[i].IsString())
                {
                    cout << "MixedArray[" << i << "] = " << array[i].GetString() << endl;
                }
                else if(array[i].IsBool())
                {
                    cout << "MixedArray[" << i << "] = " << array[i].GetBool() << endl;
                }
                else if(array[i].IsInt())
                {
                    cout << "MixedArray[" << i << "] = " << array[i].GetInt() << endl;
                }
                else if(array[i].IsDouble())
                {
                    cout << "MixedArray[" << i << "] = " << array[i].GetDouble() << endl;
                }
            }
        }
        //5.5 結構體數組類型
        if(doc.HasMember("People") && doc["People"].IsArray())
        {
            const rapidjson::Value& array = doc["People"];
            size_t len = array.Size();
            for(size_t i = 0; i < len; i++)
            {
                const rapidjson::Value& object = array[i];
                //為防止類型不匹配,一般會添加類型校驗
                if(object.IsObject())
                {
                    cout << "ObjectArray[" << i << "]: ";
                    if(object.HasMember("name") && object["name"].IsString())
                    {
                        cout << "name=" << object["name"].GetString();
                    }
                    if(object.HasMember("age") && object["age"].IsInt())
                    {
                        cout << ", age=" << object["age"].GetInt();
                    }
                    if(object.HasMember("sex") && object["sex"].IsBool())
                    {
                        cout << ", sex="  << (object["sex"].GetBool() ? "" : "") << endl;
                    }
                }
            }
        }
    }
    /**
     *    最后注意:因為rapidjson不會做安全校驗,所以要自己做安全校驗,以int整型為例
     * “if(object.HasMember("age") && object["age"].IsInt()) {}”
     * 這句校驗很重要,既要校驗有該子段,也要校驗類型正確,否則會引發程序崩潰
     */
}

還有一種解析方法,這是用於事先不知道name的前提之下,遍歷讀取,如果已知name,建議使用上面,如果不知道name,則使用下面這種方式

//遍歷解析
void parse_1()
{
    // 這個是用於遍歷json數組,用於不知道name的前提下
    string data = "{\"name\":\"qq849635649\",\"age\":20,\"sex\":true}";
    rapidjson::Document dom;
    if(! dom.Parse(data.data()).HasParseError())
    {
        for (rapidjson::Value::ConstMemberIterator iter = dom.MemberBegin(); iter != dom.MemberEnd(); ++iter)
        {
            string name = (iter->name).GetString();
            const rapidjson::Value& value = iter->value;
            if(value.IsString())
            {
                cout << name << " : " << value.GetString() << endl;
            }
            else if(value.IsInt())
            {
                cout << name << " : " << value.GetInt() << endl;
            }
            else if(value.IsBool())
            {
                cout << name << " : " << value.GetBool() << endl;
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM