• 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;
                }
            }
        }
    }
  • 相关阅读:
    DLX
    逆康托展开
    康托展开
    light oj 1427(ac自动机)
    hdu 2586 (lca-RMQ)
    约瑟夫问题
    C-运算符
    C-数据
    shell-流程控制
    python编程规范-最佳实践
  • 原文地址:https://www.cnblogs.com/mathyk/p/13047833.html
Copyright © 2020-2023  润新知