文章目录
Json是一种轻量级数据交换格式,在网络通信过程中使用非常广泛。这里介绍一下如何通过Poco库操作Json数据信息。
1.解析json字符串数据
通过Poco提供的Parser类我们可以对Json字符串进行解析
int parserJsonContent()
{
//json 输入源可以是字符串也可以是文件内容
std::string json = "{\"name\" : \"lilei\",\"age\" : 32}";
//读文件内容
Poco::File file("D:\\test.json");
std::string content;
std::ostringstream ostr;
if (file.exists())
{
Poco::FileInputStream fis("D:\\test.json", std::ios::in);
Poco::StreamCopier::copyStream(fis, ostr);
content = ostr.str();
fis.close();
}
//抓取解析过程中的错误
JSON::Parser parser;
Dynamic::Var result;
try
{
result = parser.parse(json);
}
catch (JSON::JSONException& e)
{
cout << e.message() << std::endl;
return -1;
}
//获取对象的类型并解析
if (result.type() == typeid(JSON::Object::Ptr))
{
JSON::Object::Ptr object_ptr = result.extract<JSON::Object::Ptr>();
Dynamic::Var name = object_ptr->get("name");
//指定键值不存在的时候的缺省值
std::string default_string = object_ptr->optValue<string>("name", "moren");
//判断键值的类型
if (name.type() == typeid(string))
{
string str_name = name;
}
Dynamic::Var age = object_ptr->get("age");
if (age.isInteger() || age.isNumeric())
{
int age_int = age;
}
//转成对应的动态结构体来进行访问
DynamicStruct ds = *object_ptr;
if (ds.contains("name") && ds["name"].isString())
{
string name = ds["name"];
}
if (ds.contains("age") && ds["age"].isInteger())
{
int age_int = ds["age"];
cout << age_int;
}
}
return 0;
}
2.生成Json格式的数据
通过字符串流,我们可以很方便的将Json结构类转化成对应的字符串。
int generateJsonData()
{
//生成JSON对象并转化成字符串
JSON::Object object;
object.set("name", "liming");
object.set("age", 32);
std::ostringstream ostr_stream;
object.stringify(ostr_stream);
std::string result_str = ostr_stream.str();
cout << result_str << std::endl;
//查找键值列表
JSON::Object::NameList nam_list = object.getNames();
JSON::Object parent;
parent.set("person1", object);
parent.set("pareson2", object);
std::ostringstream ostr_stream_object;
parent.stringify(ostr_stream_object);
cout << ostr_stream_object.str() << std::endl;
//生成JSON结构体并转化成字符串
//结构体和对象之间可以相互转换
//结构体可以层级嵌套使用跟Object一样
DynamicStruct my_struct;
my_struct.insert("name", "dafei");
my_struct.insert("age", 32);
string result = my_struct.toString();
cout << result << std::endl;
DynamicStruct parent_struct;
parent_struct.insert("person1", my_struct);
parent_struct.insert("person2", my_struct);
cout << parent_struct.toString() << std::endl;
return 0;
}
3.操作Json数组
int useJsonArray()
{
//生成字符串数组
JSON::Array nameArray;
nameArray.add("liming");
nameArray.add("zhanghong");
nameArray.add("wangfei");
JSON::Object root_obj;
root_obj.set("nameList", nameArray);
std::ostringstream ostr_stream_object;
root_obj.stringify(ostr_stream_object);
cout << ostr_stream_object.str() << std::endl;
Dynamic::Array struct_array;
struct_array.push_back("liming");
struct_array.push_back("zhanghong");
struct_array.push_back("wangfei");
DynamicStruct parent_struct;
parent_struct.insert("nameList", struct_array);
cout << parent_struct.toString() << std::endl;
//生成对象数组
JSON::Object object;
object.set("name", "liming");
object.set("age", 32);
JSON::Array objectArray;
objectArray.add(object);
objectArray.add(object);
objectArray.add(object);
JSON::Object obj_root_obj;
obj_root_obj.set("personList", objectArray);
std::ostringstream stream_object;
obj_root_obj.stringify(stream_object);
cout << stream_object.str() << std::endl;
//动态对象数组
Dynamic::Array obj_struct_array;
obj_struct_array.push_back(object);
obj_struct_array.push_back(object);
DynamicStruct obj_parent_struct;
obj_parent_struct.insert("structList", obj_struct_array);
cout << obj_parent_struct.toString() << std::endl;
return 0;
}
4.使用字符串流转换Json格式数据
void useStringfy()
{
std::ostringstream os;
Dynamic::Var i = 123;
JSON::Stringifier::stringify(i, os);
DateTime dt;
Dynamic::Var d = dt;
JSON::Stringifier::stringify(d, os);
JSON::Object jObj(false);
jObj.set("foo\\", 0);
jObj.set("bar/", 0);
jObj.set("baz", 0);
std::stringstream ss;
jObj.stringify(ss);
std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
JSON::Parser parser;
Dynamic::Var result;
try
{
result = parser.parse(json);
}
catch (JSON::JSONException& jsone)
{
std::cout << jsone.message() << std::endl;
return;
}
std::ostringstream ostr;
JSON::Stringifier::condense(result, ostr);
cout << ostr.str() << std::endl;
ostr.str("");
JSON::Stringifier::stringify(result, ostr, 1);
cout << ostr.str() << std::endl;
}
5.使用键值检索Json结构中的数据
int useQuery()
{
std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ], \"address\": { \"street\": \"A Street\", \"number\": 123, \"city\":\"The City\"} }";
JSON::Parser parser;
Dynamic::Var result;
try
{
result = parser.parse(json);
}
catch (JSON::JSONException& jsone)
{
std::cout << jsone.message() << std::endl;
return -1;
}
JSON::Query query(result);
//查找JSON中的某个数据,如果key不存在,或者类型不符的话返回后面的默认值
//查找children数组的第一个
std::string first_child = query.findValue("children[0]", "");
//查找某个配置项
int number = query.findValue<int>("number", 0);
//查找对象
JSON::Object address;
address.set("dummy", 123);
JSON::Object pAddress = query.findObject("address",address);
JSON::Object::Ptr pAddress_ptr = query.findObject("address");
//查找数组
JSON::Array::Ptr pChildren = query.findArray("children");
JSON::Array children;
children.add("dummy");
query.findArray("no children", children);
}
6.使用原始字符串避免字符转义
int useRawString()
{
std::string raw_string = R"json({"Name":"feifei","age":23})json";
JSON::Parser parser;
Dynamic::Var result;
try
{
result = parser.parse(raw_string);
}
catch (JSON::JSONException& e)
{
return -1;
}
DynamicStruct stru = *result.extract<JSON::Object::Ptr>();
cout << stru.toString() << std::endl;
return 0;
}
7.开启Json结构的注释模式(允许字符串中添加Json注释)
int allowCommentsInJson()
{
std::string json = "{ \"name\" : \"Franky\" /* father */, \"children\" : [ \"Jonas\" /* son */ , \"Ellen\" /* daughter */ ] }";
JSON::Parser parser;
Dynamic::Var result;
parser.setAllowComments(true);
try
{
result = parser.parse(json);
}
catch (JSON::JSONException& exception)
{
std::cout << exception.message() << std::endl;
}
return 0;
}
8.设置Json结构字符串的打印输出模式
int setformatOutput()
{
std::string json = "{ \"name\" : \"Homer\", \"age\" : 38, \"wife\" : \"Marge\", \"age\" : 36, \"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ] }";
JSON::Parser parser;
std::ostringstream ostr;
JSON::PrintHandler::Ptr pHandler = new JSON::PrintHandler(ostr);
parser.setHandler(pHandler);
parser.parse(json);
cout << ostr.str() << std::endl;
//设置缩进一个字符
pHandler->setIndent(1);
ostr.str("");
parser.reset();
parser.parse(json);
cout << ostr.str() << std::endl;
return 0;
}
9.使用Json模板结构操作字符串
void useTemplate()
{
JSON::Template tpl;
tpl.parse("Hello world! From <?= person.name?>.\n<?if person.tooOld?>You're too old.<?endif?>");
JSON::Object::Ptr data = new JSON::Object();
JSON::Object::Ptr person = new JSON::Object();
data->set("person", person);
person->set("name", "Franky");
person->set("tooOld", true);
std::ostringstream ostr;
tpl.render(data, ostr);
std::cout << ostr.str();
//ostr.str() == "Hello world! From Franky.\nYou're too old.";
}
10.Json结构的键值不自动排序保持插入顺序
int keepinsertOrder()
{
//key值的显示顺序和插入顺序保持一致
//不对key值顺序进行调整排序
JSON::Object presObj(Poco::JSON_PRESERVE_KEY_ORDER);
presObj.set("first", 0);
presObj.set("second", 0);
presObj.set("third", 0);
std::stringstream ss;
presObj.stringify(ss);
cout << ss.str() << std::endl;
std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
//引入Handler确保解析顺序和字符串中的顺序保持一致
JSON::ParseHandler::Ptr pHandler = new JSON::ParseHandler(true);
JSON::Parser parser(pHandler);
}
11.处理Json结构中转义字符
void handleEscape0()
{
Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
std::string nullString("B\0b", 3);
json->set("name", nullString);
std::stringstream ss;
json->stringify(ss);
int ret = ss.str().compare("{\"name\":\"B\\u0000b\"}");
//包含转义字符
Poco::JSON::Parser parser(new Poco::JSON::ParseHandler());
Dynamic::Var result = parser.parse(ss.str());
JSON::Object::Ptr object = result.extract<JSON::Object::Ptr>();
assert(object->get("name").extract<std::string>() == nullString);
}