I'm trying to serialize using boost property tree write_json, it saves everything as strings, it's not that data are wrong, but I need to cast them explicitly every time and I want to use them somewhere else. (like in python or other C++ json (non boost) library)
here is some sample code and what I get depending on locale:
boost::property_tree::ptree root, arr, elem1, elem2; elem1.put<int>("key0", 0); elem1.put<bool>("key1", true); elem2.put<float>("key2", 2.2f); elem2.put<double>("key3", 3.3); arr.push_back( std::make_pair("", elem1) ); arr.push_back( std::make_pair("", elem2) ); root.put_child("path1.path2", arr); std::stringstream ss; write_json(ss, root); std::string my_string_to_send_somewhare_else = ss.str();
and my_string_to_send_somewhere_else
is sth. like this:
{ "path1" : { "path2" : [ { "key0" : "0", "key1" : "true" }, { "key2" : "2.2", "key3" : "3.3" } ] } }
Is there anyway to save them as the values, like: "key1" : true
or "key2" : 2.2
?
Ok, I've solved it like this, (of course it won't suite for everybody, as it is a bit of a hack, that need further work).
I've wrote my own write_json
function (simply copied the files, json_parser.hpp
and json_parser_write.hpp
to my project) and modified the following lines in json_parser_write.hpp
:
stream << Ch('"') << data << Ch('"'); ==> stream << data;
Then values will be saved properly except for strings, so I wrote custom translator for it:
template <typename T> struct my_id_translator { typedef T internal_type; typedef T external_type; boost::optional<T> get_value(const T &v) { return v.substr(1, v.size() - 2) ; } boost::optional<T> put_value(const T &v) { return '"' + v +'"'; } };
and simply saved string using:
elem2.put<std::string>("key2", "asdf", my_id_translator<std::string>());
complete program:
#include <iostream> #include <string> #include <sstream> #include <boost/property_tree/ptree.hpp> #include "property_tree/json_parser.hpp" // copied the headers template <typename T> struct my_id_translator { typedef T internal_type; typedef T external_type; boost::optional<T> get_value(const T &v) { return v.substr(1, v.size() - 2) ; } boost::optional<T> put_value(const T &v) { return '"' + v +'"'; } }; int main(int, char *[]) { using namespace std; using boost::property_tree::ptree; using boost::property_tree::basic_ptree; try { ptree root, arr,elem2; basic_ptree<std::string, std::string> elem1; elem1.put<int>("int", 10 ); elem1.put<bool>("bool", true); elem2.put<double>("double", 2.2); elem2.put<std::string>("string", "some string", my_id_translator<std::string>()); arr.push_back( std::make_pair("", elem1) ); arr.push_back( std::make_pair("", elem2) ); root.put_child("path1.path2", arr); std::stringstream ss; write_json(ss, root); std::string my_string_to_send_somewhere_else = ss.str(); cout << my_string_to_send_somewhere_else << endl; } catch (std::exception & e) { cout << e.what(); } return 0; }
result :)
{ "path1": { "path2": [ { "int": 10, "bool": true }, { "double": 2.2, "string": "some string" } ] } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With