json的嵌套解析C++类实现

1.rapidjson简介

RapidJSON 是腾讯开源库。
RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 RapidXml。
RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
RapidJSON 快。它的性能可与 strlen() 相比。可支持 SSE2/SSE4.2 加速。
RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 “\u0000”(空字符)。

rapidjson库官网地址:http://www.oschina.net/news/61812/rapidjson-1-0-final
rapidjson库下载网地址:https://github.com/miloyip/rapidjson
rapidjson库安装及使用教程中文解释网站:http://rapidjson.org/zh-cn/

2.库的使用

1.从https://github.com/miloyip/rapidjson下载rapidjson-master.zip。
2.用如下命令解压:
[root@lc work]#unzip rapidjson-master.zip
3.将./rapidjson-master/include复制到你要编写代码的地方即可,不需要链接库。

3.代码

  • 3.1需要解析的http_im.json 文件

    //http_im.json 
    {
    "im":
    [
        {
            "domains":
            [
                {"host":"common.diditaxi.com.cn","uri":"/app/tracelog"},
                {"host":"conf.diditaxi.com.cn","uri":"/api/widgets"},
                {"host":"api.udache.com","uri":"/gulfstream/api/"},
                {"host":"car.xiaojukeji.com","uri":"/api/main"}
            ]
        }
    
    ]
    }
    
  • 3.2 myjson.h 头文件

    #include "rapidjson/document.h"
    #include <iostream>
    #include <fstream>
    using namespace rapidjson;
    using namespace std;
    class myParserJson{
    public:
        myParserJson(const string& filename);
        ~myParserJson();
        bool myParser();
        Value& getHttpObject();
        Value& getImObject();
    private:
        ifstream m_ifs;
        Document m_doc;
    };
    
  • 3.3 myjson.cpp 实现文件

    #include "myjson.h"
    myParserJson::myParserJson(const string& filename):m_doc(NULL){
        m_ifs.open(filename.c_str());
    }
    
    myParserJson::~myParserJson(){
        m_ifs.close();
    }
    Value& myParserJson::getHttpObject(){
        return m_doc["http"];
    }
    
    Value& myParserJson::getImObject(){
        return m_doc["im"];
    }
    
    bool myParserJson::myParser(){
        string mystream,line;
        if(!m_ifs){
            cout<<"open file error!"<<endl;
            return false;
        }
        while(getline(m_ifs, line)){
            mystream.append(line+"\n");
        }
        m_doc.Parse(mystream.c_str());
        assert(m_doc.IsObject());
        if(m_doc.HasParseError()){
            ParseErrorCode code = m_doc.GetParseError();
            return false;
        }
        Value& content = m_doc["im"];   //im
        assert(content.IsArray());
        for(SizeType i = 0;i<content.Size();++i){
            Value& v1 = content[i];         // {}
            assert(v1.IsObject());
            if(v1.HasMember("domains")){
                Value& v2 = v1["domains"];
                //assert(v2.IsArray()); //如果有相同名字的domains,有些却不是数组的时候不能用断言宏
                if(v2.IsArray()){
                    for(SizeType i = 0;i<v2.Size();++i){
                        Value& v3 = v2[i];  
                        if(v3.HasMember("host")){
                            cout<<"host:"<<v3["host"].GetString()<<endl;
                        }
                    }       
                }
            }
        }
    }   
    
  • 3.4 main.cpp

    #include "myjson.h"
    int main(){
        string filename = "http_im.json";
        myParserJson mj(filename.c_str());
        bool flag = mj.myParser();
        if(flag)
            cout<<"parser success!"<<endl;
        return 0;
    }
    

4.注意事项

在嵌套解析json时候,要注意是否名字相同但是却不是同类型的,例如domains,有的它是数组,有的它是object时候,不能用assert()断言宏,否则会报错!!!自己亲身实践了才知道。。。

猜你喜欢

转载自blog.csdn.net/weixin_28712713/article/details/77847505