jsoncpp动态解析节点类型
在互联网无处不在的今天,JSON作为轻量级数据存储格式,被广泛应用到互联网数据传输中。众所周知,JSON由键/值对、对象、数组组成,其中键/值对的值包括以下几种类型:
enum ValueType {
nullValue = , ///< 'null' value
intValue, ///< signed integer value
uintValue, ///< unsigned integer value
realValue, ///< double value
stringValue, ///< UTF-8 string value
booleanValue, ///< bool value
arrayValue, ///< array value (ordered list)
objectValue ///< object value (collection of name/value pairs).
};
如果在发送方和接收方间约定JSON数据格式中数据类型固定不变,那么不存在需要动态去判断节点数据类型并解析的问题。但是在实际应用过程中,存在两种情况需要支持JSON数据类型动态解析:第一,发送方因为平台迁移等种种原因导致的数据类型变化,比如本来为"key":200的键值对变成了"key":"200",这个时候如果还是按照intValue去获取key的值的话,就会解析失败; 第二,接收方不愿意一个个去按照数据类型去解析JSON数据的时候,想动态去获取数据,比如"key":20,按照stringValue和intValue都能正确的解析。
针对以上情况,本文基于jsoncpp设计了一个动态解析JSON数据的类,主要包括两个函数:
DynamicGetValue:支持解析int,uint,double,bool以及前三种类型的stringValue形式,当遇到"key":"1.23"键值对后,该函数就会进入Json::stringValue语句,通过atof函数保持了数据的精度
DynamicGetStrValue:支持解析stringValue类型以及DynamicGetValue函数支持的数据类型,在调用DynamicGetValue模板函数时,是使用的double实例化,目的是为了保证不丢失数据精度
template<typename T>
bool DynamicGetValue(Json::Value &value, T &&sValue){ //获取json int、uint、bool、double类型的值的值
bool result = true;
switch(value.type()){
case Json::stringValue:
sValue = atof(value.asString().c_str());
break;
case Json::int64Value:
sValue = value.asInt();
break;
case Json::uint64Value:
sValue = value.asUInt();
break;
case Json::booleanValue:
sValue = value.asBool();
break;
case Json::realValue:
sValue = value.asDouble();
break;
default:
result = false;
break;
}
return result;
} bool DynamicGetStrValue(Json::Value &value,string &sValue){ //获取json string、int、uint、bool、double的值
bool result = true;
double nValue = -;
if(value.type() == Json::stringValue){
sValue = value.asString();
}
else if(DynamicGetValue<double&>(value, nValue)){
sprintf((char*)sValue.data(),"%.8f", nValue);
}
else{
result = false;
}
return result;
}
针对上动态数据类型解析函数,设计了如下测试试用例,这里我们把strJson数据中的"data1":1,"data2":3.1415927两个键值对当做stringValue类型来解析,能够正确的获取数据。但是切记,不能将"msg"和"code"调用DynamicGetValue解析,因为它们只能用stringValue来表达,只能调用DynamicGetStrValue解析,所以这里DynamicGetStrValue是万能的,能解析任何类型的数据。
int main(){
string strJson = "{\"msg\":\"正常\", \"code\":\"A0000\", \"data1\":1,\"data2\":3.1415927, \"data3\":-4}";
Json::Reader reader;
Json::Value root;
Json::Value value;
if (!reader.parse(strJson, root, false))
{
return;
}
string msg_,code_,strValue1,strValue2;
unsigned int data1;
double data2;
int data3;
if(root.isMember("msg")){
value = root["msg"];
DynamicGetStrValue(value,msg_);
}
if(root.isMember("code")){
value = root["code"];
DynamicGetStrValue(value,code_);
}
if(root.isMember("data1")){
value = root["data1"];
DynamicGetValue(value,data1);
}
if(root.isMember("data2")){
value = root["data2"];
DynamicGetStrValue(value,strValue1);
}
if(root.isMember("data3")){
value = root["data3"];
DynamicGetStrValue(value, strValue2);
}
char strVal[]={} ;
sprintf(strVal,"%s, %s, %d, %s, %s", msg_.c_str(), code_.c_str(), data1, strValue1.c_str(), strValue2.c_str());
return ;
}
上测试用例输出如下图,正确的获取了data1和data2的值,达到了动态解析JSON数据类型的目的。
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAASUAAAAzCAYAAADRnx5FAAAElElEQVR4nO3cPW7qWhiF4XWu7gA8BidSJMoUnoGdgooiPSU0RxRQMAKKpIjS+JT0p6BKEZiBC0qkSInH4BncWwCJcfwX/8AmeR8pSoyx2d42K9+2Db+iKPpPAGCIf07dAACII5QAGIVQAmAUQgmAUXJDKfQ9jVbxR1Yaeb7CdtsE4Af7lX31LZTvPepyIt3ezrPX0P+r6MFtp3UAfpzsSil81qLTles+KIqi3c9f9Z2Z1u/T0UEghb4na7TSamTJOiyxPuZ7vvyRJc+n3gLwWWYohc8L6epC24rJkmVZsqxbzYOprq3ddHwoF/oaLHpaP7hyu31p/qTDWAr1vAjUnww1fFirtxiIXAKQlBFKKz1Og9i0o9k6Vh1FkaL1TE58icepOpOhbElyu+prrqd4KoXPWgR9dV1JsjWcdDR9/FxNAfjZUkMp9O+0ceKRE2h6va+Wdj/XU33EVqjXjbMtrCRJrrbF0kfohM8LBf2u3gd7F1dyNq/bSiv05VkelROA9FB6U0+TXvyRokrpTS9BR5f2xxLu75mc9yHcbujWjZ0Qty/VCV701uTWADh7qaHkDoe6OHikoFIKX7Vxrg6XsW/Uc3ZDuIOh296FrpyNXkNJ9lDLaKmhLQA/XMmbJwsqpdSqx9ZNz9H8afV56CYprboCgJKhVHROSZJ2VU+MfdOTM7/TYCHNfifuZQpftXn/m3NKALaaqZTkqtsP9JI8QWTfqOcECtTTTbIientJqZ4A/HSZd3SHvqeBeupMp8q5n1tyZlovh7JDX95A+rPc3RaQK5S/fTLnkQAcyPmYydeFvqfrl0nhx05WI0t3V2stSSQACY2GEgDUxVeXADAKoQTAKIQSAKMQSgCMQigBMMq/aQ+Ox+NjtwMAJGWEkiTd398fsx0AIOkIwzfLsgr/BoC9zEoprkyARFGU+bhlWQfzk9MAsFcqlJIBUiZUkkG2n07+Tlt/HVlty3u9NubV0XRo12lnUVvy+juvv9LaU6Wv66yzTV/dh8c+Pk1+P5QKparKNOwYw7i8Sq2NeXXb2qQ67azalrzlsl67Tl9nhdC5VOjHPj5Nfz+0FkrxxuY9p40Kw9SDr4x9+5tcX1ttyZrX9DbkMTF0OF9aT+lQqrPDi4ZTOD/xfwBfXW6v7PFkQtCUVbVf8KFypZTs9KLzDjit/T449Ru8TGVTVJ2dahvyKkM0p3IoVfkvd4wDigBMlzX2r6LqOvKWiVcXWZVG3use49gqc3GHgKqv1RPdWQdWXFM78VxOan4XeSeU85YpCqaqy5qiSr/gUKuhJOVXSnmhdc47s41tqLrOouqiyjrbuupY9kpOU9We1Ow+KnOsn/NxfSyth1KWJq/cxO99ii+/n06uM3k5ue15dbal7jrz2lm1LUXzy25D1rymLoy0tY+KFPVb0qmPz7bnfVXq1+GOx+P3z759Zcc1Meb+DiVvG9vwHfrFJPSnuQorpbbK22O83qm0sQ3foV9MQn+ai+9TAmAUQgmAUQglAEYhlAAYhVACYBRCCYBRCCUARiGUABiFUAJgFEIJgFEIJQBGIZQAGOV/C/NG7I+HCxAAAAAASUVORK5CYII=" alt="" />
jsoncpp动态解析节点类型的更多相关文章
- C#匿名类型和动态解析减少定义传输类模板
C#作为强类型语言,在序列化和反序列化(json)场景中对字符串解析常常需要定义强类型模板,造成编码上的繁琐.其实可以使用匿名类型和动态解析减少json序列化时候的数据模板定义: string a = ...
- 深入理解DOM节点类型第七篇——文档节点DOCUMENT
× 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...
- jquery 源码解析 节点遍历
jquery遍历,用于根据其相对于其他元素的关系来查找或选取html元素,以某项选择开始,并沿着这个选择移动,知道移动被称为对dom进行遍历 ☑ <div> 元素是 <ul> ...
- DOM Element节点类型详解
上文中我们讲解了 DOM 中最重要的节点类型之一的 Document 节点类型,本文我们继续深入,谈谈另一个重要的节点类型 Element . 1.概况 Element 类型用于表现 HTML 或 X ...
- Mybatis 系列6-结合源码解析节点配置:objectFactory、databaseIdProvider、plugins、mappers
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- Mybatis 系列4-结合源码解析节点:typeAliases
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- 使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)
在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象 ...
- 深入理解DOM节点类型第五篇——元素节点Element
× 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...
- 深入理解DOM节点类型第一篇——12种DOM节点类型概述
× 目录 [1]元素 [2]特性 [3]文本[4]CDATA[5]实体引用[6]实体名称[7]处理指令[8]注释[9]文档[10]文档类型[11]文档片段[12]DTD 前面的话 DOM是javasc ...
随机推荐
- mysql之 binlog维护详细解析(开启、binlog相关参数作用、mysqlbinlog解读、binlog删除)
binary log 作用:主要实现三个重要的功能:用于复制,用于恢复,用于审计.binary log 相关参数:log_bin设置此参数表示启用binlog功能,并指定路径名称log_bin_ind ...
- python——爬虫&问题解决&思考(四)
继续上一篇文章的内容,上一篇文章中已经将url管理器和下载器写好了.接下来就是url解析器,总的来说这个模块是几个模块中比较难的.因为通过下载器下载完页面之后,我们虽然得到了页面,但是这并不是我们想要 ...
- HTML----网页基础和基本标签
网页分类: 1.静态网页:所有内容全写死,都写在源代码中,若修改必须修改源代码,后缀为.html或htm 2.动态网页:内容大部分来自于数据库,可以修改,后缀为.aspx(c#).jsp(java). ...
- 如何动态加载js文件,$.getScript()方法的使用
有时候我们需要动态在页面中加载js文件,jquery封装了getScript()方法,不用自己再创建标签了. 写法: $.getScript("name.js",function( ...
- c++ const char *[] or char [][]
]={"hello","world"}; ]={"hello"};char (*ch3)[6]= ch1; std::cout<< ...
- Vulkan Tutorial 13 Render passes
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Setup 在我们完成管线的创建工作,我们接下来需要告诉Vulkan渲染时候使用的f ...
- Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)
最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所 ...
- 用Nodejs做一个简单的小爬虫
Nodejs将JavaScript语言带到了服务器端,作为js主力用户的前端们,因此获得了服务器端的开发能力,但除了用express搭建一个博客外,还有什么好玩的项目可以做呢?不如就做一个网络爬虫吧. ...
- js___原生js轮播
原生js轮播 作为一名前端工程师,手写轮播图应该是最基本掌握的技能,以下是我自己原生js写的轮播,欢迎指点批评: 首先css代码 a{text-decoration:none;color:#3DBBF ...
- 设计模式(2)工厂方法模式(Factory Method)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 源码地址 0 工厂方法模式简介 0.0 工厂方法模式定义 工厂方法模式是在简单工厂模式基础上,为解决更复杂的对象创建问题而衍生 ...