一、JSON定义
JavaScript Object Notation
由字符串
化的键值对构成,总的来说就是一个字符串表示的对象。
1. 是一种数据交换格式
虽然一开始用于JavaScript,但是主要是用于web中的数据交换,就是一种数据交换格式,而且很好懂,很易读,也有利于数据传输。
2.支持的数据类型(值的数据类型)
- 对象:
{}
括起来的键值对,用逗号,
分隔,键值格式是键:值
,json本身就是一个对象
。 - 数值:十进制,支持科学计数法
- 字符串:
""
括起来的0~n个字符,支持转义字符 - 布尔:true、false
- 数组:
[]
括起来的多个值,以,
分割 - 空:null
3. 例子:
{
"version": "test_json v1.0",
"description": "this demo used to practice json analysis",
"test_number": "78322",
"path_set": {
"load_path": ".\/data",
"save_path": ".\/result"
},
"camera_device": {
"name": "cam1",
"path": "\/sys\/dev\/",
"FOV": [
"30",
"50"
],
"RES": [
"640",
"480"
],
"Intrinsic": {
"fx": "50.2155",
"fy": "45.1245",
"cx": "0.55454",
"cy": "0.55488"
}
},
"T_Matrix": {
"t1": [
"1",
"2",
"3"
],
"t2": [
"4",
"5",
"6"
]
},
"other_info": {
"info_1": {
"info": "hello world",
"Matrix": [
"21",
"21",
"21",
"21"
]
},
"info_2": {
"info": "hello C++",
"Matrix": [
"22",
"22",
"22",
"22"
]
}
},
"location1": [
"23",
"23",
"2333"
],
"location2": [
"233",
"233",
"23333"
],
"test_choice": [
{
"name": "test1",
"enable": "true"
},
{
"name": "test2",
"enable": "false"
},
{
"name": "test1",
"enable": "true"
}
],
"end_desc": "thank you"
}
二、使用boost:构造、读取、写入、增删查改
<boost/property_tree/ptree.hpp>
负责构造<boost/property_tree/json_parser.hpp>
负责以json格式输出
1. 构造数组
#include <boost/property_tree/ptree.hpp>
namespace pt = boost::property_tree;
pt::tree root;
pt::ptree child1, child2,child3, child4;
pt::ptree childs;
//单独一个数值
child1.put("", 2);
//单独一个字符串
child2.put("", "asdh");
//对象
child3.put("key0", "val0");
//构造数组,主意childs必须只有key为""的,不能有其他。不然会退化为对象
//把数值加入数组
childs.push_back(make_pair("", child1));
childs.push_back(make_pair("", child2));
childs.push_back(make_pair("", child3));
childs.push_back(make_pair("", childs));
//键为list,值为childs数组
root.put("list", childs);
/*
{
"list":
[
2,
"asdh",
{"key0", "val0"},
[2, "asdh", {"key0", "val0"}]
]
}
*/
2. 从文件/流读入,写入到流/文件
使用头文件#include <boost/property_tree/json_parser.hpp>
实现读取和写入json
- 从文件读入(给文件名)
#include <boost/property_tree/json_parser.hpp>
namespace pt = boost::property_tree;
string file_name = "./test.json";
pt::ptree json_root;
pt::read_json(file_name , json_root);
- 从流读入,文件流
ifstream
和string流stringstream
都行
string file_name = "./test.json";
ifstream fs;
fs.open(file_name);
pt::read_json(fs, json_root);
- 写入文件(给文件名)
pt::write_json(filename, json_root);
- 写入流,文件流或string流,true代表美化,false代表不美化,美化就是换行,如果ss是stringstream,注意传输的时候用
ss.str()
,cout << ss.str() << endl;
pt::write_json(ss, json_root, true);
false=
{"version":"test_json v1.0","description":"this demo used to practice json analysis","test_number":"78322","path_set":{"load_path":".\/data","save_path":".\/result"},"camera_device":{"name":"cam1","path":"\/sys\/dev\/","FOV":["30","50"],"RES":["640","480"],"Intrinsic":{"fx":"50.2155","fy":"45.1245","cx":"0.55454","cy":"0.55488"}},"T_Matrix":{"t1":["1","2","3"],"t2":["4","5","6"]},"other_info":{"info_1":{"info":"hello world","Matrix":["21","21","21","21"]},"info_2":{"info":"hello C++","Matrix":["22","22","22","22"]}},"location1":["23","23","2333"],"location2":["233","233","23333"],"test_choice":[{"name":"test1","enable":"true"},{"name":"test2","enable":"false"},{"name":"test1","enable":"true"}],"end_desc":"thank you","a":{"info_1":{"info":"hello world","Matrix":["21","21","21","21"]},"info_2":{"info":"hello C++","Matrix":["22","22","22","22"]}},"b":{"load_path":".\/data","save_path":".\/result"}}
true=
{
"version":"test_json v1.0",
"description":"this demo used to practice json analysis",
"test_number":78322,
"path_set":{
"load_path":"./data",
"save_path":"./result"
},
"camera_device":{
"name":"cam1",
"path":"/sys/dev/",
"FOV":[30,50],
"RES":[640,480],
"Intrinsic":{
"fx":50.2155,
"fy":45.1245,
"cx":0.55454,
"cy":0.55488
}
},
"T_Matrix":{
"t1":[1,2,3],
"t2":[4,5,6]
},
"other_info":{
"info_1":{
"info":"hello world",
"Matrix":[21,21,21,21]
},
"info_2":{
"info":"hello C++",
"Matrix":[22,22,22,22]
}
},
"location1":[23,23,2333],
"location2":[233,233,23333],
"test_choice":[
{
"name":"test1",
"enable":true
},
{
"name":"test2",
"enable":false
},
{
"name":"test1",
"enable":true
}
],
"end_desc":"thank you"
}
3. 添加
add
:add(key, value)
,add_child可以用来添加数组和对象
add 不会覆盖原来的key:value,也就是
root.add("list", "1234");
root.add("list", "1234");
/*
{
"list":"1234",
"list":"1234"
}
*/
put
和put_child和add类似,不同的是put对于相同的key:value并不会重复添加,也就是
root.put("list", "1234");
root.put("list", "1234");
/*
{
"list":"1234",
}
*/
push_back/push_front
:提供一个pair,必须是键:对象/数组
root.push_back(make_pair("123", child1));
如果单纯想插入一个非对象和数组的值,可以这样
childs2.put("", "sda");
root.push_back(make_pair("123", childs2));
4. 查找
- 查找值(非数组和对象)
string value0 = root.get<string>("key0");
double value1 = root.get<double >("key1");
int value2 = root.get<int>("key2");
bool value3 = root.get<bool>("key3");
- 查找对象/数组
pt::ptree value4 = root.get_child("key4");
- 遍历:
- 范围for
对于数组,可以用下边这种来获取每一个数组的值
- 范围for
for (pt::ptree::value_type &value : value4)
{
//2.获得每一个子节点的值,并将其放进vector
T tValue =value.second.get_value<T>();
vecData.push_back(tValue);
}
-
- 迭代器,其中getArrayDataFromJson是把数组存到vector
pt::ptree::iterator it;
for(it = ele_other.begin();it!=ele_other.end();it++)
{
cout << it->first << endl;;
//对每个子节点对象(即sub_value.second)进行解析
string sub_info_temp = it->second.get<string>("info");
vector<int> sub_v_temp;
bool sub_v_temp_flag = getArrayDataFromJson(sub_v_temp,it->second,"Matrix");
cout<<sub_info_temp<<"=[";
for(auto v:sub_v_temp)cout<<v<<" ";
cout<<"]"<<endl;
}
//解析普通数组
template <class T>
bool getArrayDataFromJson(std::vector<T> &vecData, pt::ptree & nodeJSON, string path) {
//1.循环遍历数组中所有的子节点(数组中的每一个元素)
for (pt::ptree::value_type &value : nodeJSON.get_child(path))
{
//2.获得每一个子节点的值,并将其放进vector
T tValue =value.second.get_value<T>();
vecData.push_back(tValue);
}
return true;
}
5.删除
- 使用erase(key)删除键key的所有值
root.erase("list");
6.修改
- 通过迭代器修改:
root.begin()->second.put_value("wasdasd");
- 通过键修改:注意只适合对象中的键唯一,不然只会找到第一个key对应的,如果有多个建议用迭代器修改
root.get_child("list").put_value("asd");