• Poco库使用:操作Json格式数据



    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    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;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    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);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    9.使用Json模板结构操作字符串

    void useTemplate()
    {
    	JSON::Template tpl;
    	tpl.parse("Hello world! From .\nYou're too old.");
    
    	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.";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    爱创科技携手洽洽食品,探索渠道数字化最优解!
    Docker数据存储&容器之间数据共享
    有关CSS的芝士
    Docker部署青龙面板
    UNet涉及的重点函数记录
    软件工程毕业设计课题(71)微信小程序毕业设计PHP校园浴室预约小程序系统设计与实现
    设计模式面试题
    用户端APP自动化测试_L2
    正式发布丨VS Code 1.70
    理性推广 | C1N短网址帮您节省运营成本!
  • 原文地址:https://blog.csdn.net/yang1fei2/article/details/126817113