Closed coolhandle01 closed 6 years ago
I am not sure whether producing non-compliant JSON text is in the scope of this library. However, I do not fully understand your use case. Could you please provide the exact desired output for the JSON value
{
"some_object": {
"happy": true,
"pi": 3.141
}
}
As JSON, I'd like it as it is - in C++ land, I'd like a string representation of the object without the surrounding quotes, so that I can inject it into the last %s here: boost::format("var %s = %s.%s(%s)")
I am building a JavaScript based on JSON data. json.h -> C++ string representing an object -> string inserted into another string(via format/str) -> write to file.
So how would the JSON above look like?
Sorry for inflicting confusion here!
The JSON is something like this:
{
"Calls":
[
{
"var": "returned_value",
"fn": "named_method",
"args":
{
"some_object": {
"happy": true,
"pi": 3.141
}
}
},
...
]
}
And I'd like to generate the following string as painlessly as possible, before I write it to some_script.js:
var returned_value = KnownThing.named_method({ "some_object": {"happy": true, "pi": 3.141 }});
So you want
{
"some_object": {
"happy": true,
"pi": 3.141
}
}
to become
{ "some_object": {"happy": true, "pi": 3.141 }}
?
Nono, Indentation is not an issue or concern here.
When I call dump, I'd like
{ "some_object": {"happy": true, "pi": 3.141 }}
but I get
"{ "some_object": {"happy": true, "pi": 3.141 }}"
in fact in the debugger it looks like this:
\"{ "some_object": {"happy": true, "pi": 3.141 }}\"
(last I checked, might be going insane on this project)
and so I have to dequote the string result of .dump() with some hacky method, before writing the said string to some .js.
Like:
auto js = boost::str(boost::format("var %s = %s.%s(%s)"), varname, objname, methodname, args);
where auto args = j.dump();
I'm really struggling to make this clearer!
How did you parse the JSON text? Did you use parse
to did you write something like json j = "..."
?
It is impossible for the code you provided to produce the string "{ "some_object": {"happy": true, "pi": 3.141 }}"
because your code dumps "some_object"
. Can you verify that the code you provided is the same as what you're using?
I've worked around it now, because I obviously can't have random symbols in the JSON (variables), so I'm representing var references as strings, and doing a search, so I'm no longer using j.dump()
with boost::format. Let me prepare a standalone example to emulate what I was doing. I will return soon with code.
Any news on this?
I have a similar requirement. Keep the keys unquoted optionally. This can be done by passing a flag to the dump()
function. Also I need a verbatim
type value which will have string content but dump will not put quotes around it.
Without quotes, dump
would produce invalid JSON text. If you want such a function, you can traverse the values yourself recursively and produce the desired result. I do not see this as part of the API.
Hi Niels, I've been meaning to get back to you, apologies for not doing so sooner.
In the end I traversed the values as suggested, and probably ended up with better code for what I was trying to achieve - essentially writing a script where blocks from the JSON are args to the methods (but didn't want to parse the JSON str on the other side of the JS to make the object).
I moved the goalposts by changing the API I was targeting to methods accepting individual args instead of objects, to make things easier.
I do think it's a bit wierd that the dump() method gives you escaped quotes though, as I've never seen a json file where the first character was a " - always { or [, but its fairly likely you've seen more exotic json that I.
Quote weirdness I can deal with, and that aside, this library is brilliant, and I am grateful for it :)
I do think it's a bit wierd that the dump() method gives you escaped quotes though, as I've never seen a json file where the first character was a " - always { or [, but its fairly likely you've seen more exotic json that I.
We only escape quotes inside strings, and this is required by the JSON specification, see
This is not weird, it is the only correct way to produce a valid JSON text.
Perhaps you can use something along these lines. Perhaps Niels can tell if this is the way to go:
/** Converts an json object to a string representation.
Similar to json.dump() but without the quotes.
Assumes that the object is not structured (ie. primitive).
For structured object a empty string is returned.
Special values like null, numbers etc. are converted to
string representation.
*/
std::string to_string(const nlohmann::json& object)
{
if (object.is_structured()) return "";
if (object.is_null()) return "null";
else if (object.is_string()) return object.get<std::string>();
else if (object.is_boolean()) return object.get<bool>() ? "true" : "false";
else if (object.is_number_float()) return std::to_string(object.get<double>());
else if (object.is_number_integer()) return std::to_string(object.get<long>());
else if (object.is_number_unsigned()) return std::to_string(object.get<unsigned long>()); // Seems unused
else if (object.is_number()) return std::to_string(object.get<double>()); // Seems unused
else {
// Fallback in case we forgot an if above!
std::string s = object.dump();
return s.substr(1, s.length() -2) + " FIXMENM";
}
}
You could simplify this to code like
std::string to_string(const nlohmann::json& j)
{
switch (j.type())
{
// avoid escaping string value
case value_t::string:
return j.get<std::string>();
case value_t::array:
case value_t::object:
return "";
// use dump() for all other value types
default:
return j.dump();
}
}
I've been having similar issues. I see this question being asked a few times, so didn't wish to open another ticket. This seemed like the appropriate place to ask (if there's still life here). Full example code
pos posarr[3];
char posname[16];
int i;
posarr[0].x = 10;
posarr[0].y = 11;
sprintf(posname, "pos1");
memcpy(posarr[0].name, posname, sizeof(posarr[0].name));
posarr[1].x = 20;
posarr[1].y = 21;
sprintf(posname, "pos2");
memcpy(posarr[1].name, posname, sizeof(posarr[1].name));
posarr[2].x = 30;
posarr[2].y = 31;
sprintf(posname, "pos3");
memcpy(posarr[2].name, posname, sizeof(posarr[2].name));
nlohmann::json positem, posxlist, posylist, posnamelist;
for (i = 0; i < 3; ++i)
{
positem = posarr[i].x;
posxlist.push_back(positem);
positem = posarr[i].y;
posylist.push_back(positem);
positem = posarr[i].name;
posnamelist.push_back(positem);
}
nlohmann::json allpos = {
{"x", posxlist.dump()},
{"y", posylist.dump()},
{"name", posnamelist.dump()},
{"items", i}
};
dlog_print(DLOG_DEBUG, scServiceLogTag, "EXAMPLE OUTPUT |%s|", allpos.dump().c_str());
outputs
EXAMPLE OUTPUT |{"items":3,"name":"[\"pos1\",\"pos2\",\"pos3\"]","x":"[10,20,30]","y":"[11,21,31]"}|
The string variables have \
escape characters (is this a separate issue?), and the arrays are wrapped as strings. What I'm looking for / expecting is
EXAMPLE OUTPUT |{"items":3,"name":["pos1","pos2","pos3"],"x":[10,20,30],"y":[11,21,31]}|
I've tried to replace .dump()
when building allpos
with get<std::string>()
as suggested in some tickets, but the app crashes at runtime, possibly because it's not actually a string, but a JSON array? (Tizen 4.0 Wearable - if that's relevant)
Just don't call dump, so the value remains of type json. It is then properly escaped.
@nlohmann , oh my gosh. Perfect. Thank you so much. And also, I'm really impressed by both the project and your amazing support.
Feature Request
First up, amazing library. Love it. Definitely going to play well with V8 and V8PP, so well done.
What is the issue you have? My issue is that j.dump() returns a string in quotes for objects, and I have no way to disable this. I'd like to .dump() something I can build strings with using boost::format without having to write my own dequoting method and suddenly thinking about complexity of string ops. That's your job! ;P
Please describe the steps to reproduce the issue. Can you provide a small but working code example? Simplifying to Pseudo-esque code:
What is the expected behavior? I don't want the quotes on my string-dumped object (others probably do).. I'd like dump to be extended with default parameter bool bQuoted=true so I can set it false. auto formatted = boost::str(matic% j.at("some_object").dump(false)); //formatted == "var fn = function() { return; }".
// no quotes
And what is the actual behavior instead? I get the quotes, see above. see line 8505 in the header of 2.11
Which compiler and operating system are you using? Is it a supported compiler? MSVC 2015 on Win10 Pro
Did you use a released version of the library or the version from the
develop
branch?If you experience a compilation error: can you compile and run the unit tests? I'm using 2.11 from the releases page
Describe the feature in as much detail as possible. make quotes surrounding dumped objects an option
Include sample usage where appropriate. auto str = j.dump(-1, false);