1

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" : "[email protected]",
            "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?

3
  • Did you try responseDataCart = responseData[0]["cart"]["name"]; Commented Jan 2, 2019 at 12:29
  • Yes, i tried - it doesn't work. Commented Jan 2, 2019 at 12:30
  • Your return statement is wasteful. toStyledString() already gives you a std::string, which only needs directly returning (which will move it); you're obtaining a C-string out of it then constructing a new string from that. It's not the end of the world, but it does require a strlen invocation and prohibits moving the data. Commented Jan 2, 2019 at 12:42

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for the reply! Works perfectly with Json::CharReader* reader = jsonReader.newCharReader();
@MichaelK. Don't forget to delete it! I like to use std::unique_ptr for the task. I had a memory leak in production where I was doing auto reader = Json::CharReaderBuilder().newCharReader(); and forgot that it returns a naked pointer :( Needless to say that area of code now has a massive comment warning slapped all over it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.