here is the json I want to parse:
{"jsonrpc":"2.0","method":"subscription","params":{"channel":"book.BTC-PERPETUAL.raw","data":{"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",60772.0,50.0], "demo"],"asks":[]}}}
and here is my code to get the values from a child:
boost::property_tree::ptree pt; boost::property_tree::read_json(ss, pt);
std::cout << "\njsonrpc: " << pt.get<std::string>("jsonrpc") << std::endl;
std::cout << "\nmethod: " << pt.get<std::string>("method") << std::endl;
std::cout << "\nparams: " << pt.get<std::string>("params") << std::endl;
std::cout << "\nparams.channel: " << pt.get<std::string>("params.channel") << std::endl;
std::cout << "\nparams.data: " << pt.get<std::string>("params.data") << std::endl;
std::cout << "\nparams.data.timestamp: " << pt.get<std::string>("params.data.timestamp") << std::endl;
std::cout << "\nparams.data.instrument_name: " << pt.get<std::string>("params.data.instrument_name") << std::endl;
but when I tried to parse the array values like ("params.data.bids") it return nothing
I need help in parsing an array
CodePudding user response:
You should use a JSON Library:
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
int main() {
auto req = json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})") .as_object();
auto& params = req["params"].as_object();
auto& data = params["data"].as_object();
std::cout << "jsonrpc: " << req["jsonrpc"].as_string() << "\n";
std::cout << "methdo: " << req["method"].as_string() << "\n";
std::cout << "params.channel: " << params["channel"].as_string() << "\n";
std::cout << "params.data: " << params["data"] << "\n";
std::cout << "params.data.timestamp: " << data["timestamp"] << "\n";
std::cout << "params.data.instrument_name: " << data["instrument_name"] << "\n";
}
Prints
jsonrpc: "2.0"
methdo: "subscription"
params.channel: "book.BTC-PERPETUAL.raw"
params.data: {"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",6.0772E4,5E1],"demo"],"asks":[]}
params.data.timestamp: 1635513739435
params.data.instrument_name: "BTC-PERPETUAL"
bid: ["new",6.0772E4,5E1]
bid: "demo"
Adding the asks/bids:
for (auto& bid : data["bids"].as_array()) {
std::cout << "bid: " << bid << "\n";
}
for (auto& ask : data["asks"].as_array()) {
std::cout << "ask: " << ask << "\n";
}
Prints
bid: ["new",6.0772E4,5E1]
bid: "demo"
Alternative / Bonus
You can also use value_to
conversion to your own types:
struct request {
std::string jsonrpc, method;
struct params_t {
std::string channel;
struct data_t {
std::string type;
size_t timestamp, prev_change_id, change_id;
std::string instrument_name;
std::vector<json::value> bids, asks;
} data;
} params;
};
See it Live
Or flattened:
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
See it Live As Well
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
int main() {
auto req = value_to<request>(json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})"));
std::cout << "jsonrpc: " << req.jsonrpc << "\n";
std::cout << "methdo: " << req.method << "\n";
std::cout << "params.channel: " << req.channel << "\n";
std::cout << "data.timestamp: " << req.timestamp << "\n";
std::cout << "data.instrument_name: " << req.instrument_name << "\n";
for (auto& bid : req.bids) std::cout << "bid: " << bid << "\n";
for (auto& ask : req.asks) std::cout << "ask: " << ask << "\n";
}