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

JSON Creation #1461

Closed
fkicenko opened this issue Jan 29, 2019 · 6 comments
Closed

JSON Creation #1461

fkicenko opened this issue Jan 29, 2019 · 6 comments
Labels
state: needs more info the author of the issue needs to provide more details state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated

Comments

@fkicenko
Copy link

fkicenko commented Jan 29, 2019

Hello,
I'm trying to create a JSON structure that contains Arrays and Objects that are hierarchical. Could spend a considerable amount of time but thought I would post my questions first. I'm having issues creating Objects (key:value) pairs eg: "modelSeries":"520", within an Array. Also creating Arrays within Arrays. I'm attaching a JSON file that i'm working on and below is the code i've created so far. Hopefully someone can shed some light on the easiest way to do this.

Code:

// create an empty structure 
	json j;
	// Update the template configuration version
	std::string standardString = marshal_as<std::string>(hsConfig->getTemplateVersion());
	j["headsetConfig"]["templateConfiguration"]["configTemplateVersion"] = standardString;
	// Update the Timestamp
	hsConfig->setUpdateTime(strTemp);
	standardString = marshal_as<std::string>(hsConfig->getUpdateTime());
	j["headsetConfig"]["templateConfiguration"]["updatedTime"] = standardString;
	// Update the ReportId
	standardString = marshal_as<std::string>(hsConfig->getReportId());
	j["headsetConfig"]["templateConfiguration"]["reportId"] = standardString;
	// Add the Model Specific array of models
	json mSpecificSettings = j.array();
	// Loop through the Models
	// Set all the models for this series
	json models = { "models" };
	json mModelSeries;
	for each(ModelSpecific^ ms in hsConfig->ModelSpecificList)
	{
		String^ s = ms->getModelSeries();
		standardString = marshal_as<std::string>(s);
		mModelSeries = { {"modelSeries", standardString } };

		mSpecificSettings.push_back({ {"modelSeries", standardString } });
		// Build the models array eg:521, 522, 523
		json models250 = j.array();
		for each(String^ mds in ms->modelList)
		{
			standardString = marshal_as<std::string>(mds);
			models250.insert(models250.end(), standardString);
		}
		mSpecificSettings.push_back(models250);
		//mModelSeries.insert(mModelSeries.end(), models250);
	}
	j["headsetConfig"]["templateConfiguration"]["modelSpecificSettings"] = mModelSeries;
	// write prettified JSON to another file
	std::ofstream o("pretty.json");
	o << std::setw(4) << j << std::endl;

headsetJSON.zip

@arrtchiu
Copy link

arrtchiu commented Jan 30, 2019

Relying on the brace-initialization is a little bit funny in this library and might vary depending on your compiler (see #1359). I'd be explicit about use of object vs array, and also break it up into smaller pieces (functions/lambdas depending on your style). Doing it like this also help avoid typo bugs (which still compile fine) by not repeating the keys several times.

json j = json::object();
j["headsetConfig"] = [] {
  json headsetConfig = json::object(); // note I am explicitly specifying I want this to be an object
  headsetConfig["templateConfiguration"] = [] {
    json templateConfiguration = json::object();
    templateConfiguration["configTemplateVersion"] = "1";
    // ...
    templateConfiguration["someArray"] = [] {
      json someArray = json::array(); // note I am explicitly specifying I want this to be an array
      for (auto const& thing : collection) {
        someArray.push_back(JsonObjectForThing(thing));
      }
    }();
    return templateConfiguration;
  }();
  return headsetConfig;
}();

For even cleaner code (those lambdas are pretty ugly!) you can provide your own overloads to to_json.

@nlohmann
Copy link
Owner

@fkicenko Do you need further assistance?

@fkicenko
Copy link
Author

Hey... the lambda's simply don't work here... Is there a more elegant way to do this with this library? The JSON structure is really simple enough. Thanks for the help!

@arrtchiu
Copy link

IMO overloading to_json is your best bet. It's simple and elegant. The documentation is also very good: https://github.com/nlohmann/json#basic-usage

Here's an example with nesting:

#include <iostream>
#include <iomanip>

#include <nlohmann/json.hpp>

struct Foo {
	std::string value;
};

struct Bar {
	int value;
};

struct Nested {
	Foo foo;
	Bar bar;
};

using json = nlohmann::json;

void to_json(json& j, Foo const& f) {
	j["foo_value"] = f.value;
}

void to_json(json& j, Bar const& b) {
	j["bar_value"] = b.value;
}

void to_json(json& j, Nested const& n) {
	j["foo"] = n.foo;
	j["bar"] = n.bar;
}

int main(int argc, const char** argv) {
	Nested serialiseMe{{"myname"}, {42}};
	json serialised(serialiseMe);
	std::cout << std::setw(2) << serialised << std::endl;
	return 0;
}

@fkicenko
Copy link
Author

Ok this is good... If you can give me an example of nesting an Array within an Object I think i'm good to go. This example gives me 2 objects but just fuzzy on now nesting an Array in there. Thanks!!!

@nlohmann
Copy link
Owner

Can you provide an example of the input, the current output, and the expected output?

@nlohmann nlohmann added the state: needs more info the author of the issue needs to provide more details label Mar 10, 2019
@nlohmann nlohmann added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Mar 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: needs more info the author of the issue needs to provide more details state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated
Projects
None yet
Development

No branches or pull requests

3 participants