<!--toc-->
|
|
## Introduction
|
|
[JSON](http://json.org/) is a lightweight structured
|
data interchange format. Unlike XML it is very easy
|
to parse format. More then that in comparison to XML it contains much higher signal to noise ratio.
|
|
CppCMS recommend using JSON as data interchange format
|
and it uses this format for CppCMS configuration file
|
that is accessible via `cppcms::service::settings()`
|
member function.
|
|
CppCMS provides a powerful class `cppcms::json::value` that
|
allows to format, parse and operate over JSON data.
|
|
## Operating On JSON data.
|
|
There are three major objects in `cppcms::json` namespace:
|
|
- `value` - the universal container that can hold objects, arrays and scalar values
|
- `array` - `std::vector<value>` - array of values
|
- `object` - `std::map<string_key,value>` - mapping between strings and values.
|
|
For given:
|
|
cppcms::json::value my_object;
|
|
We can easily add new members to our object:
|
|
my_object["name"]="Moshe";
|
my_object["salary"]=1000.0;
|
my_object["kids_names"][0]="Yossi";
|
my_object["kids_names"][1]="Yonni";
|
my_object["data"]["weight"]=85;
|
my_object["data"]["height"]=1.80;
|
With this small code we created an object like:
|
|
{
|
"name" : "Moshe",
|
"salary" : 1000.0,
|
"kids_names" : [ "Yossi" , "Yonni" ],
|
"data" : {
|
"weight" : 85,
|
"height" : 1.80
|
}
|
}
|
|
When we access operator `[]` of non-const object we
|
automatically create a JSON object or JSON array depending
|
on the type of the parameter (textual - object, numerical - array).
|
|
The array is automatically extended when we try to access
|
"empty" spots.
|
|
|
We can easily access values using operator `[]` and
|
member functions like `number()`, for example:
|
|
double salary = my_object["salary"].number();
|
std::string name = my_object["name"].str();
|
|
Or we can use `get` member function and specify a full
|
path to the required object:
|
|
double salary = my_object.get<double>("salary");
|
double height = my_object.get<double>("data.height");
|
|
We can also provide some default values in case the
|
given path does not exist or has different type:
|
|
std::string eyes_color = my_object.get("data.eyes_color","brown");
|
|
|
## JSON Input and Output
|
|
`cppcms::json::value` has operators `>>` and `<<`
|
with `std::istream` and `std::ostream` respectively,
|
so you can easily save JSON data as:
|
|
out << my_object
|
|
And read it as
|
|
in >> my_object
|
|
You can also use `save` and `load` member functions
|
to have grater control over the way the objects are written
|
and read.
|
|
For example, pretty print JSON object:
|
|
my_object.save(std::cout,cppcms::json::readable);
|
|
Read the input and make sure we got to EOF:
|
|
my_object.load(tmp,true);
|
|
|
## C++ Class JSON Object conversion
|
|
It is possible to define a conversion between C++ and
|
JSON objects. It can be done by specializing
|
`cppcms::json::traits` class.
|
|
For example, we have a object person:
|
|
struct person {
|
std::string name;
|
double salary;
|
std::vector<std::string> kids_names;
|
};
|
|
We can define a method for converting between `person`
|
and `cppcms::json::value` by specializing the `traits` class:
|
|
|
namespace cppcms {
|
namespace json {
|
template<>
|
struct traits<person> {
|
...
|
};
|
} // json
|
} // cppcms
|
|
|
The specialized traits class should include two static
|
member functions `get` and `set`:
|
|
|
The "getter:"
|
|
static person get(value const &v)
|
{
|
person p;
|
if(v.type()!=is_object)
|
throw bad_value_cast();
|
|
p.name=v.get<std::string>("name");
|
p.salary=v.get<double>("salary");
|
p.kids_names=
|
v.get<std::vector<std::string> >("kids_names");
|
return p;
|
}
|
|
First we check that the type is "Object" otherwise
|
we throw `bad_value_cast`. Note this step is not
|
really necessary as `v.get<std::string>("name")` would
|
throw `bad_value_cast` in case `v` is not an object.
|
|
But it is useful to see how errors should be reported: by
|
throwing `cppcms::json::bad_value_cast`.
|
|
Then we setup different member functions.
|
|
Note this line:
|
|
v.get<std::vector<std::string> >("kids_names");
|
|
It works because `std::vector` and many other standard
|
C++ containers are already specialized so `std::vector<std::string>` is expected to be an
|
array of JSON strings.
|
|
Our setter is similar:
|
|
static void set(value &v,person const &in)
|
{
|
v.set("name",in.name);
|
v.set("salary",in.salary);
|
v.set("kids_names",in.kids_names);
|
}
|
|
|
As above we save `std::vector<std::string>` automatically.
|
|
Now we can convert between `value` and person as
|
any other scalar before:
|
|
person moshe = my_object.get_value<person>();
|
some_object["stuff"]["head"] = moshe;
|
moshe = some_object.get<moshe>("stuff.head");
|
|
|
## Further Reading
|
|
Take a look [JSON Namespace](/cppcms_ref_v0_99/namespacecppcms_1_1json.html) reference manual.
|
|
## Syntax Extensions
|
|
CppCMS supports some non-standard JSON syntax that makes
|
it suitable for configuration file format:
|
|
1. It allows C++ style comments `//`
|
2. It allows trailing commas in objects and arrays.
|
|
Thus following syntax is accepted by the JSON parser:
|
|
{
|
"foo" : 10,
|
"bar" : 20, // Note trailing comma
|
// "baz" : 30 -- this is a comment
|
}
|
|
---
|
|
|
← [Serialization][prev]
|
| [Top](#maincontent)
|
| [JSON RPC][next] →
|
|
[prev]: /wikipp/en/page/cppcms_1x_serialization
|
[next]: /wikipp/en/page/cppcms_1x_json_rpc |