How to use boost::property_tree to load and write JSON
来源:互联网 发布:hessian java 编辑:程序博客网 时间:2024/06/06 00:42
Boost's Property Tree
Property Tree is a sublibrary of boost that allow you handlingtree of property. It can be used to represent XML, JSON, INI files, file paths, etc. In our case, we will be interested in loading and writing JSON, to provide an interface with other applications.
Our example case will be the following json file :
{ "height" : 320, "some" : { "complex" : { "path" : "hello" } }, "animals" : { "rabbit" : "white", "dog" : "brown", "cat" : "grey" }, "fruits" : ["apple", "raspberry", "orange"], "matrix" : [[1, 2, 3], [4, 5, 6], [7, 8, 9]]}
Reading data
Let's have a look at how we can load those data into our c++ application.
Setting up
First, we need to include the libraries and load the file.
#include <boost/property_tree/ptree.hpp>#include <boost/property_tree/json_parser.hpp>// Short alias for this namespacenamespace pt = boost::property_tree;// Create a rootpt::ptree root;// Load the json file in this ptreept::read_json("filename.json", root);
Now, we have a populated property tree thatis waiting from us to look at him. Notice that you can also read from a stream, for examplept::read_json(std::cin, root)
is also allowed.
If your json file is illformed, you will be granted by a pt::json_parser::json_parser_error
.
Loading some values
We can access a value from the root by giving it's path to the get
method.
// Read valuesint height = root.get<int>("height", 0);// You can also go through nested nodesstd::string msg = root.get<std::string>("some.complex.path");
If the field your are looking to doesn't exists, the get()
method will throw apt::ptree_bad_path
exception, so that you can recorver from incomplete json files. Notice you can set a default value as second argument, or useget_optional<T>()
wich return a boost::optional<T>
.
Notice the getter doesn't care about the type of the input in the json file, but only rely on the ability to convert the string to the type you are asking.
Browsing lists
So now, we would like to read a list of objects (in our cases, a list of animals).
We can handle it with a simple for loop, using an iterator. In c++11, it become :
// A vector to allow storing our animalsstd::vector< std::pair<std::string, std::string> > animals;// Iterator over all animalsfor (pt::ptree::value_type &animal : root.get_child("animals")){ // Animal is a std::pair of a string and a child // Get the label of the node std::string name = animal.first; // Get the content of the node std::string color = animal.second.data(); animals.push_back(std::make_pair(name, color));}
Since animal.second
is a ptree
, we can also call callget()
orget_child()
in the case our node wasn't just a string.
A bit more complexe example is given by a list of values. Each element of the list is actualy astd::pair("", value)
(where value is aptree
). It doesnt means that reading it is harder.
std::vector<std::string> fruits;for (pt::ptree::value_type &fruit : root.get_child("fruits")){ // fruit.first contain the string "" fruits.push_back(fruit.second.data());}
In the case the values arent string, we can just call fruit.second.get_value<T>()
in place offruit.second.data()
.
Deeper : matrices
There is nothing now to enable reading of matrices, but it's a good way to check that you anderstood the reading of list. But enought talking, let's have a look at the code.
int matrix[3][3];int x = 0;for (pt::ptree::value_type &row : root.get_child("matrix")){ int y = 0; for (pt::ptree::value_type &cell : row.second) { matrix[x][y] = cell.second.get_value<int>(); y++; } x++;}
You can now read any kind of JSON tree. The next step is being able to read them.
Writing JSON
Let's say that now, we wan't to produce this tree from our application's data. To do that, all we have to do is build aptree
containing our data.
We start with an empty tree :
pt::ptree root;//...// Once our ptree was constructed, we can generate JSON on standard outputpt::write_json(std::cout, root);
Add values
Puting values in a tree can be acomplished with the put()
method.
root.put("height", height);root.put("some.complex.path", "bonjour");
As you can see, very boring.
Add a list of objects
No big deel here, although we now use add_child()
to put our animal
node at the root.
// Create a nodept::ptree animals_node;// Add animals as childsfor (auto &animal : animals) animals_node.put(animal.first, animal.second);// Add the new node to the rootroot.add_child("animals", animals_node);
Add many nodes with the same name
Now start the tricky tricks. If you want to add more than one time a node namedfish
, you can't call theput()
method. The callnode.put("name", value)
will replace the existing node namedname
. But you can do it by manually pushing your nodes, as demonstrated bellow.
// Add two objects with the same name pt::ptree fish1; fish1.put_value("blue"); pt::ptree fish2; fish2.put_value("yellow"); oroot.push_back(std::make_pair("fish", fish1)); oroot.push_back(std::make_pair("fish", fish2));
Add a list of values
If you remember, list are mades of nodes with empty name. Se we have to build node with empty names, and then use thepush_back()
once again to add all those unnamed childs.
// Add a listpt::ptree fruits_node;for (auto &fruit : fruits){ // Create an unnamed node containing the value pt::ptree fruit_node; fruit_node.put("", fruit); // Add this node to the list. fruits_node.push_back(std::make_pair("", fruit_node));}root.add_child("fruits", fruits_node);
Add a matrix
We already have all the tools needed to export our matrix. But let's demonstrate how to do it.
// Add a matrixpt::ptree matrix_node;for (int i = 0; i < 3; i++){ pt::ptree row; for (int j = 0; j < 3; j++) { // Create an unnamed value pt::ptree cell; cell.put_value(matrix[i][j]); // Add the value to our row row.push_back(std::make_pair("", cell)); } // Add the row to our matrix matrix_node.push_back(std::make_pair("", row));}// Add the node to the rootroot.add_child("matrix", matrix_node);
References
You can download a C++ example and the input JSON file for experimenting. Compile it with clang++ -std=c++11 example.cpp -o example
.
Some links related :
- The official documentation
- A post on stack overflow
Rem : At the moment, the boost::property_tree library doesn't output typed value. But we can expect that it will be corrected soon.
- How to use boost::property_tree to load and write JSON
- How to use java Properties API -- read and write
- How to read and write JSON files in Java(Gson)
- how to use the boost library
- How to use whiptail to write interactive shell scripts
- How to use write and run MapReduce in eclipse on windows.
- 如何使用 How to use json-lib
- how to write your annotation types and make use of built-in annotations to control their behavior
- How to install and use doxygen
- How to Create and Use the DLL
- How To Use Function 'F4_FILENAME' and 'KD_GET_FILENAME_ON_F4'
- standard exception and how to use
- How to use 'SetItemData()' and 'GetItemData()'?
- How to use the CONVERSION_EXIT_PARVW_INPUT and CONVERSION_EXIT_PARVW_OUTPUT
- How To Choose and Use Strong Passwords
- how to config and use apt-get
- What and How to use JSF
- How to use NSString and NSMutableString
- UIView的alpha、hidden和opaque属性之间的关系和区别
- HDU 6038(Function) 思维 Java
- NVIDIA Nsight Eclipse 安装
- 项目中期客户拜访随行小记
- Linux yum提示Another app is currently holding the yum lock; waiting for it to exit...
- How to use boost::property_tree to load and write JSON
- MySQL、SqlServer、Oracle数据库之间的差异
- HDU-2602-Bone Collector(01背包)
- JSP特点
- 最长公共子序列poj1458
- 【dp专题1】hdu1003 D
- ajax调用php时,php执行eval导致服务器500错误
- Cordova使用Plugman创建插件—拨打电话 拨号页面 发送短信
- Q