使用JsonCpp解析Json string

2021-03-03  本文已影响0人  louyang

Json可以理解为取代XML的一种数据格式,类似的还有YAML

下面是来自维基百科的一个Json例子:

{
     "firstName": "John",
     "lastName": "Smith",
     "sex": "male",
     "age": 25,
     "address": 
     {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": "10021"
     },
     "phoneNumber": 
     [
         {
           "type": "home",
           "number": "212 555-1234"
         },
         {
           "type": "fax",
           "number": "646 555-4567"
         }
     ]
 }

JsonCpp是一个读取Json数据的c++工具库,本文将由简入繁最终用JsonCpp来提取维基百科这个Json例子中的各元素。

1 安装jsoncpp

在CentOS 8上安装JsonCpp的方法:

sudo dnf -y install epel-release
sudo dnf -y install jsoncpp jsoncpp-devel

在Ubuntu 2004 LTS上安装JsonCpp的方法:

sudo apt install libjsoncpp-dev

2 第一个解析Json字符串

Jsoncpp提供下面API来解析Json字符串:

class JSON_API Reader {
public:
    bool parse(const std::string& document, Value& root, bool collectComments = true);

这个接口已经进入了不推荐使用的状态。我们之所以先用这个接口编程,是因为这个接口简单,容易理解。后续我们会看到最新的替代其的接口。

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

std::string str =
"{\
  \"Name\":\"Tom\",\
  \"Age\":20\
}";

int main()
{
    Json::Reader reader;
    Json::Value root;
    if (reader.parse(str, root)) {
        std::cout << "A: " << root["A"].asString() << std::endl;
        std::cout << "B: " << root["B"].asString() << std::endl;
    } else {
        std::cout << "parse error" << std::endl;
    }
    return 0;
}

编译运行:

$ g++ a.cpp -l jsoncpp && ./a.out
Name: Tom
Age: 20

3 使用最新的接口

旧接口是这样的:

    Json::Reader reader;
    Json::Value root;
    if (reader.parse(str, root)) {

新接口是这样,可以完全替代旧接口:

#include <memory>

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::Value root;
    std::string err;
    if (reader->parse(str.c_str(), str.c_str()+str.size(), &root, &err)) {

完整代码:

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>

std::string str =
"{\
  \"Name\":\"Tom\",\
  \"Age\":20,\
  \"Children\":[\"Peter\",\"John\"]\
}";

int main()
{
//    Json::Reader reader;
//    Json::Value root;
//    if (reader.parse(str, root)) {

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::Value root;
    std::string err;
    if (reader->parse(str.c_str(), str.c_str()+str.size(), &root, &err)) {

        std::cout << "Name: " << root["Name"].asString() << std::endl;
        std::cout << "Age: " << root["Age"].asInt() << std::endl;

        int n = root["Children"].size();
        std::cout << n << " Children:" << std::endl;

        for (int i = 0; i < n; i++) {
            std::string e = root["Children"][i].asString();
            std::cout << e << " ";
        }
        std::cout << std::endl;
    } else {
        std::cout << "parse error" << std::endl;
    }
    return 0;
}

编译运行:

$ g++ a2.cpp -l jsoncpp && ./a.out
Name: Tom
Age: 20
2 Children:
Peter John 

4 解析Json文件

Jsoncpp提供的API如下:

bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);

准备Json文件:

$ cat a.json
{
    "A":"a",
    "B":"b"
}

源代码:

#include <iostream>
#include <fstream>
#include <jsoncpp/json/json.h>

int main()
{
    std::ifstream ifs {"a.json"};
    Json::Reader reader;
    Json::Value root;
    reader.parse(ifs, root);
    std::cout << "A: " << root["A"].asString() << std::endl;
    std::cout << "B: " << root["B"].asString() << std::endl;
    return 0;
}

编译运行:

$ g++ c.cpp -l jsoncpp && ./a.out
A: a
B: b

5 解析维基百科中的Json例子

$ cat b.json
{
     "firstName": "John",
     "lastName": "Smith",
     "sex": "male",
     "age": 25,
     "address": 
     {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": "10021"
     },
     "phoneNumber": 
     [
         {
           "type": "home",
           "number": "212 555-1234"
         },
         {
           "type": "fax",
           "number": "646 555-4567"
         }
     ]
 }
#include <iostream>
#include <fstream>
#include <jsoncpp/json/json.h>

int main()
{
    std::ifstream ifs {"b.json"};
    Json::Reader reader;
    Json::Value root;
    reader.parse(ifs, root);

    std::cout << root["lastName"].asString() << " " << root["firstName"].asString() << " ";
    std::cout << root["address"]["streetAddress"].asString() << " "
              << root["address"]["city"].asString() << " "
              << root["address"]["state"].asString() << " ";
    std::cout << root["phoneNumber"][0]["type"].asString() << " "
              << root["phoneNumber"][0]["number"].asString() << std::endl;
    return 0;
}
$ g++ d.cpp -l jsoncpp && ./a.out
Smith John 21 2nd Street New York NY home 212 555-1234

6 参考

1 使用JsonCpp构造Json string https://www.jianshu.com/p/909a2eb4d3ebj
2 JsonCpp项目网站的example

上一篇 下一篇

猜你喜欢

热点阅读