Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-level JSON support. #775

Closed
horntones opened this issue Oct 10, 2017 · 10 comments
Closed

multi-level JSON support. #775

horntones opened this issue Oct 10, 2017 · 10 comments
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@horntones
Copy link

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

@gregmarr
Copy link
Contributor

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

@horntones
Copy link
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

@nlohmann
Copy link
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

@gregmarr
Copy link
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.

@gregmarr
Copy link
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";
}

@horntones
Copy link
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!

@gregmarr
Copy link
Contributor

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

@horntones
Copy link
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";
	}

@gregmarr
Copy link
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.

@horntones
Copy link
Author

That worked! Totally appreciate your help on this!

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Oct 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants