Rapidjson parse another json if first one has errors - c++

Say I have a JSON string and it has an error and thus can not be parsed. Then I want to parse another JSON string, which will replace the original one. I want to do that using the same rapidjson::Document as eventually I need to have parsed the valid JSON in that document.
So:
rapidjson::Document document;
if (document.Parse<0>("{ \"hello\" : \"wor........ ").HasParseError())
{
// How to parse the correct json "{ \"hello\" : \"world\" }" here
// using the same `Document` ?
}
Should I just write
if (document.Parse<0>("{ \"hello\" : \"wor........ ").HasParseError())
{
document.Parse<0>("{ \"hello\" : \"world\" }");
}

Yes, if first parsing hes error then parsing another JSON by using the same document is OK, as far as it clears that data and parses newly.

Related

Parsing Json using arduino-mqtt lib

I am trying to use the arduino-mqtt lib.
I have this working sending the json string. The problem comes with trying to parse the string with ArduinioJson. It just returns no value.
I think it may have todo with the pointer reference in the mqttMessageRecived function ( String &payload).
Function called when there is an MQTT message:
void mqttMessageReceived(String &topic, String &payload){
//Example String for test
String json = "{"id" : "100" , "cmd" : "0xff"}";
jsonout(payload);
Serial.println("Sending Static String");
jsonout(json);
Function to parse json input:
void jsonout(String Json){
StaticJsonDocument<200> doc;
//Deserialize the JSON document
DeserializationError error = deserializeJson(doc, Json);
Serial.println("Got String: ");
Serial.println(Json);
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
const char* id = doc["id"];
const char* cmd = doc["cmd"];
// Print values.
Serial.println(id);
Serial.println(cmd);
}
Non parsed output:
Message from MQTT
Got String:
"{\"id\" : 4 , \"cmd\": \"0xee\"}"
Result = No output from json parse
Non parsed output:
Sending Static String
Got String:
{"id" : "100" , "cmd" : "0xff"}
Result = Output from json parse:
100
0xff
The problem is that - in the response from the server
"{\"id\" : 4 , \"cmd\": \"0xee\"}"
the id field is an integer - not a character array.
So you need to change
const char* id = doc["id"];
to
int id = doc["id"];
(and update your test string to use an int for the ID also).
The server returns a id member that's a Number "id":4, while you are generating a id that's a String "id":"200".
You need to adjust your code to either one. If it's a number (and it seems so), you need to send "id":200 and change your code to get a number:
unsigned id = (double)doc["id"];
// And to generate it:
String json = "{\"id\" : 100 , \"cmd\" : \"0xff\"}";
Also, with JSON, beware of hexadecimal encoding, has it's not converted to number (you have to do it yourself by receiving a const char* and calling sscanf or strtol or ...) and it's not convenient. It's better to use base-10 encoding instead:
String json = "{\"id\" : 100 , \"cmd\" : 255}";

c++ JsonCpp parse string with escaped quotes as array

I've got the following json string:
{
"data" :
[
{
"cart" : "[{\"name\":\"Test item 1\",\"price\":15,\"quantity\":1,\"sum\":15,\"tax\":\"none\",\"payment_type\":\"advance\",\"item_type\":\"service\"},{\"name\":\"Test item 2\",\"price\":13.01,\"quantity\":2,\"sum\":26.02,\"tax\":\"none\",\"payment_type\":\"part_prepay\",\"item_type\":\"work\"}]",
"contact" : "noname#google.com",
"p_id" : "603",
"sum" : "100.02",
"tax_system" : "osn"
}
],
"msg" : null,
"result" : "success"
}
I can parse cart as std::string after parsing input json string as stringstream:
const std::string ParseJsonData(std::stringstream ssJsonStream)
{
Json::Value jsonData;
Json::Value responseData;
Json::Value responseDataCart;
Json::CharReaderBuilder jsonReader;
std::string errs;
if (Json::parseFromStream(jsonReader, ssJsonStream, &jsonData, &errs)) {
responseData = jsonData["data"];
responseDataCart = responseData[0]["cart"];
return responseDataCart.toStyledString().c_str();
}
else
return "Could not parse HTTP data as JSON";
}
Please, tell me, how can i parse cart as array with JsonCpp?
The same way you parsed the outer JSON!
You started with a string (well, hidden by a stream) and turned it into JSON.
Now that JSON contains a property that is a string and, itself, contains JSON. The problem is recursive. The fact that the inner string originally came from JSON too can be ignored. Just pretend it's a string you typed in.
So, you can use JSON::Reader to in turn get the JSON out of that string.
Something like:
const std::string responseDataCartStr = responseData[0]["cart"].asString();
Json::Reader reader;
if (!reader.parse(responseDataCartStr, responseDataCart))
throw std::runtime_error("Parsing nested JSON failed");
JsonCpp provides a few ways to parse JSON and it's worth exploring them to find the most appropriate for your use case. The above is just an example.
Ignore the backslashes — the escaping was meaningful within the encapsulating JSON document, but the outermost parse stage should already have taken that into consideration. You'll see if you print responseDataCartStr to console that it is a valid JSON document in its own right.

bsonxx::from_json convert all value types to string

I am using Boost's Property Tree library for storing my json files. For example,
I have the following JSON file:
{
"var" : true,
"bar" : -1.56
}
Next I parse this file to ptree object, do my job and want to store output in MongoDB. For this I convert it back to JSON string:
boost::property_tree::ptree root;
boost::property_tree::read_json(file_path, root);
... // do my job
std::stringstream ss;
boost::property_tree::json_parser::write_json(ss, root);
std::string my_json_string = ss.str();
After this I push my results to MongoDB, by converting JSON string to BSON like this: bsonxx::from_json(my_json_string). As result I receive the following entity in database:
{
"var" : "true",
"bar" : "-1.56"
}
Is there a way to insert my JSON string to MongoDB with persistence types?

How to create empty json object correctly using web.json in cpp?

I want to create following json request:
{
"Value1":{},
"Value2":"some string value"
}
to achieve this I have tried following code in cpp:
json::value &refRequest
json::value jRequest = json::value();
refRequest[requestKey::Value1] = json::value(json::value::object()); //for creating empty object
refRequest[requestKey::Value2] = json::value::string("some string");
but it gives output as:
{
"Value1":},
"Value2":"some string value"
}
if you observe, instead of returning empty object as {} it gives the output as } and this results in to malformed request. I am not sure where exactly I am going wrong, any help will would be appreciated. Thanks
I believe your mistake is that you are constructing a json::value from a json::value::object()
According to the documentation the line should be fixed to:
refRequest[requestKey::Value1] = json::value::object();

Not able to get values from JSON in Casablanca, C++

I'm using Casablanca, cpprestsdk to consume REST APIs in C++, in Visual Studio 2015 Professional. I'm trying to develop a simple example here hitting an API and parsing the response as JSON. The URL I'm using, actually returns all the parameters sent to the API.
I've hit the API and got response as well, extracted json from the response successfully. But when i try to read a value at any key from json, it crashes. Hence i put a check whether that key is available or not, and it always says json does not have the field. As an example i printed the data i.e. json. It has the key/field "name" but when i check it via has_field, it returns false.
Please help.
Complete code is below :
json::value postData;
postData[L"name"] = json::value::string(L"Joe Smith");
postData[L"sport"] = json::value::string(L"Baseball");
http_client client(L"https://httpbin.org/post);
http_request request(methods::POST);
request.set_body(postData);
client.request(request).then([](web::http::http_response response) {
json::value j = response.extract_json().get();
json::value data = j.at(U("data"));
std::wcout << "Json : " << data;
// Prints "{\"name\":\"Joe Smith\",\"sport\":\"Baseball\"}"
if (data.has_field(U("name"))) {
std::cout << "Name Found";
}
else {
std::cout << "Name key not Found";
}
});
It seems that your response looks like this:
{ "data": "{\"name\":\"Joe Smith\",\"sport\":\"Baseball\"}" }`
i.e. the actual data is not a JSon object but escaped JSon passed as string. I guess you need to return a payload that looks like this to do what you want to do the way you are doing it:
{
"data": {
"name": "John Smith",
"sport": "Baseball"
}
}