在互联网无处不在的今天,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动态解析节点类型的更多相关文章

  1. C#匿名类型和动态解析减少定义传输类模板

    C#作为强类型语言,在序列化和反序列化(json)场景中对字符串解析常常需要定义强类型模板,造成编码上的繁琐.其实可以使用匿名类型和动态解析减少json序列化时候的数据模板定义: string a = ...

  2. 深入理解DOM节点类型第七篇——文档节点DOCUMENT

    × 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...

  3. jquery 源码解析 节点遍历

    jquery遍历,用于根据其相对于其他元素的关系来查找或选取html元素,以某项选择开始,并沿着这个选择移动,知道移动被称为对dom进行遍历 ☑ <div> 元素是 <ul> ...

  4. DOM Element节点类型详解

    上文中我们讲解了 DOM 中最重要的节点类型之一的 Document 节点类型,本文我们继续深入,谈谈另一个重要的节点类型 Element . 1.概况 Element 类型用于表现 HTML 或 X ...

  5. Mybatis 系列6-结合源码解析节点配置:objectFactory、databaseIdProvider、plugins、mappers

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  6. Mybatis 系列4-结合源码解析节点:typeAliases

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  7. 使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)

    在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象 ...

  8. 深入理解DOM节点类型第五篇——元素节点Element

    × 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...

  9. 深入理解DOM节点类型第一篇——12种DOM节点类型概述

    × 目录 [1]元素 [2]特性 [3]文本[4]CDATA[5]实体引用[6]实体名称[7]处理指令[8]注释[9]文档[10]文档类型[11]文档片段[12]DTD 前面的话 DOM是javasc ...

随机推荐

  1. mysql5.6 rpm安装配置

    检查MySQL及相关RPM包,是否安装,如果有安装,则移除(rpm –e 名称)   [root@localhost share]# rpm -qa | grep -i mysql MySQL-cli ...

  2. 在host-only模式下ssh不插网线

    visualbox在host-only模式下,宿主机可以在没有网络的条件下ssh虚拟机. 设置方法: 1.在visualbox中,选择全局设置(preference)--网络(network)-- h ...

  3. Redis 小白指南(二)- 基础命令和五大类型:字符串、散列、列表、集合和有序集合

    Redis 小白指南(二)- 基础命令和五大类型:字符串.散列.列表.集合和有序集合 引言 目录 基础命令 字符串类型 散列类型 列表类型 集合类型 有序集合类型 基础命令 1.获得符合规则的键名列表 ...

  4. "php-cgi.exe - FastCGI 进程意外退出" 解决办法

    问题描述: win7下iis中php-cgi.exe - FastCGI 进程意外退出 错误提示: HTTP 错误 500.0 - Internal Server Error D:\phpStudy\ ...

  5. Javaweb---服务器Tomcat与Eclipse的关联

    1.与eclipse的关联 打开eclipse-->window-->preferences 在搜索框输入->server->进行搜索,选择-–>server and R ...

  6. css 中的背景图片小技巧和存在的坑

    body 的背景图设置 第一种 :这种情况下背景图片可以缩放 但是不能完全等比缩放 background: url(imgs/1.jpg)no-repeat; background-position: ...

  7. Coursera 机器学习笔记(三)

    主要为第四周.第五周课程内容:神经网络 神经网络模型引入 之前学习的线性回归还是逻辑回归都有个相同缺点就是:特征太多会导致计算量太大.如100个变量,来构建一个非线性模型.即使只采用两两特征组合,都会 ...

  8. 测序分析软件-phred的安装

    1.进入phred官网,给作者写信,获得所需的软件,大约需要两三天的时间即可收到回信. 2.根据作者的指示下载,解压相应软件. 3.以笔者本人的安装为例unbuntu系统(phred自带的instal ...

  9. redis学习(2)--- Redis概述

    一.Redis介绍 高性能键值对数据库,支持的键值对数据类型: 字符串类型 列表类型 有序集合类型 散列类型 集合类型 官方测试读写速度: 测试50个并发程序,执行10万次请求 读的速度:每秒11万次 ...

  10. Spring学习(1)----入门学习(附spring-framework下载地址)

    (一)Spring是什么 Spring是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在已经不止应用于企业应用 是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架- 从大小和开销 ...