Skip to content

multi-level JSON support. #775

Closed
Closed

Description

@horntones

Hi,
I'm using json.hpp in an attempt to create a jason object from a json string. It appears that it only supports single hierarchy json. for example, I'm trying to parse the following:

std::string myString = "{ "Meta Data": { "1. Information": "Intraday (1min) prices and volumes", "2. Symbol" : "MSFT"}, "Time Series (1min)":{"2017-10-09 16:00:00": {"1. open": "76.3300","2. high" : "76.3400","3. low" : "76.2900"},"2017-10-09 15:59:00": {"1. open": "76.3200","2. high" : "76.3350"} }}";

json j = json::parse(myString);

when I print the json, I only get the top keys parsed:
Meta Data : {"1. Information":"Intraday (1min) prices and volumes","2. Symbol":"MSFT"}
Time Series (1min) : {"2017-10-09 15:59:00":{"1. open":"76.3200","2. high":"76.3
350"},"2017-10-09 16:00:00":{"1. open":"76.3300","2. high":"76.3400","3. low":"7
6.2900"}}

Any advise?
thanks!
Mike

Activity

  1. gregmarr commented on Oct 10, 2017

    @gregmarr
    Contributor

    How are you printing them? Can you also give the exact code you're using to parse? The code above is invalid.

  2. horntones commented on Oct 10, 2017

    @horntones
    Author

    //create string
    std::string myString = "{ "Meta Data": { "1. Information": "Intraday (1min) prices and volumes", "2. Symbol" : "MSFT"}, "Time Series (1min)":{"2017-10-09 16:00:00": {"1. open": "76.3300","2. high" : "76.3400","3. low" : "76.2900"},"2017-10-09 15:59:00": {"1. open": "76.3200","2. high" : "76.3350"} }}";
    //parse into json
    json j = json::parse(myString);
    //print json
    for (json::iterator it = j.begin(); it != j.end(); ++it) {
    std::cout << it.key() << " : " << it.value() << "\n";
    }
    results in:
    Meta Data : {"1. Information":"Intraday (1min) prices and volumes","2. Symbol":"MSFT"}
    Time Series (1min) : {"2017-10-09 15:59:00":{"1. open":"76.3200","2. high":"76.3
    350"},"2017-10-09 16:00:00":{"1. open":"76.3300","2. high":"76.3400","3. low":"7
    6.2900"}}

    Thanks for taking the time to look at this!
    Mike

  3. nlohmann commented on Oct 10, 2017

    @nlohmann
    Owner

    You are iterating over the top-level object. If you want to iterate the "sub-objects", you need to iterate over it->value().begin(), it->value().end().

    Maybe related: https://stackoverflow.com/questions/45934851/c-nlohmann-json-how-to-iterate-find-a-nested-object

  4. gregmarr commented on Oct 10, 2017

    @gregmarr
    Contributor

    Your first line of code still won't compile, due to unquoted quotes within the string. Assuming that you're actually properly quoting these, or reading this from a file or something, then the parse looks to be fine, and you just need to handle objects within your loop, as @nlohmann described.

  5. gregmarr commented on Oct 10, 2017

    @gregmarr
    Contributor

    When posting code, you should indent all the lines by at least 4 characters, and leave a blank line before and after. This will make github display your code as code, with the proper spacing.

    //create string
    std::string myString = "{ "Meta Data": { "1. Information": "Intraday (1min) prices and volumes", "2. Symbol" : "MSFT"}, "Time Series (1min)":{"2017-10-09 16:00:00": {"1. open": "76.3300","2. high" : "76.3400","3. low" : "76.2900"},"2017-10-09 15:59:00": {"1. open": "76.3200","2. high" : "76.3350"} }}";
    //parse into json
    json j = json::parse(myString);
    //print json
    for (json::iterator it = j.begin(); it != j.end(); ++it) {
        std::cout << it.key() << " : " << it.value() << "\n";
    }
    
  6. horntones commented on Oct 10, 2017

    @horntones
    Author

    Thank you for the tip for posting code. I'm not sure this library is going to work for me as it doesn't readily support nested json. (it->value().begin(), it->value().end() method) does not compile. I'm simply trying to parse out a multi-level json data like the example shown into an array that I can use for analysis and graphing.
    any suggestions on methodology (besides writing my own parser) would be appreciated.
    thanks again!

  7. gregmarr commented on Oct 10, 2017

    @gregmarr
    Contributor

    It supports nested json just fine. Did you read the stackoverflow post above?

  8. horntones commented on Oct 10, 2017

    @horntones
    Author

    I did.
    So I tried navigating the hierarchy. As only the top level key pairs are parsed. I tried parsing the value associated with the top key pairs. This would work nicely, however it throws and exception when tying to parse j_meta. Pardon my novice-ness here, I'm a hardware guy that used to write C many moons ago. Just getting back in the swing of things... and how they've changed. :)

    	std::string myString = "{ \"Meta Data\": { \"1. Information\": \"Intraday (1min) prices and volumes\", \"2. Symbol\" : \"MSFT\"}, \"Time Series (1min)\":{\"2017-10-09 16:00:00\": {\"1. open\": \"76.3300\",\"2. high\" : \"76.3400\",\"3. low\" : \"76.2900\"},\"2017-10-09 15:59:00\": {\"1. open\": \"76.3200\",\"2. high\" : \"76.3350\"} }}"; 
    
            json j = json::parse(myString);
    
    	// iterate the array
    
    	for (json::iterator it = j.begin(); it != j.end(); ++it) {
    		if (it.key() == "Meta Data") {
    			std::cout << "Meta Data Found!\n\t" << it.value() << std::endl;
    			//output here is: 
    				//Meta Data Found!
    				//	{"1. Information":"Intraday (1min) prices and volumes", "2. Symbol" : "MSFT"}
    			std::cout << "Parsing Meta Data..." << std::endl;
    			json j_meta = json::parse(it.value().get<std::string>());  //Exception Thrown here
    			//print the items
    			for (json::iterator it_meta = j_meta.begin(); it_meta != j_meta.end(); ++it) {
    				std::cout << "\t" << it_meta.key() << "  " << it_meta.value() << std::endl;
    			}
    		}
    		//std::cout << it.key() << std::endl; //: " << it.value() << "\n";
    	}
    
  9. gregmarr commented on Oct 10, 2017

    @gregmarr
    Contributor

    It's parsing the entire thing. It may look like it's not because when you write it to cout it dumps it back to a json string. Remove the second json::parse line, and replace j_meta with it.value() in the second for loop and you should get what you want.

  10. horntones commented on Oct 10, 2017

    @horntones
    Author

    That worked! Totally appreciate your help on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    solution: proposed fixa fix for the issue has been proposed and waits for confirmation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions