在互联网无处不在的今天,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. Windows平台下python2和3的兼容问题解决

    很多朋友都安装了python2和3,因为用些库例如scapy,不是scrapy,python3下面都是错,那么怎么让python2和3共存呢. 像一般的程序员,达到如下效果 Windows平台下的兼容 ...

  2. linux下载安装phpmyadmin

    phpmyadmin下载: https://www.phpmyadmin.net/downloads/ 1.解压缩 tar -zxvf phpMyAdmin-4.7.1-all-languages.t ...

  3. javascript基础-语法

    代表此属性ECMAScript 5(一般IE9+)才支持. 图解:—— 图解: undefined,null,NaN Infinity ECMAScript 5禁止修改 每个函数都是Function的 ...

  4. (转)java匿名内部类详解

    原文:http://android.blog.51cto.com/268543/384844/   内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的 ...

  5. 设计模式一:关于C++写观察者模式的一些收获

    先贴上部分代码: #include "stdafx.h" #include<iostream> #include<string> #include<v ...

  6. javascript代码的小小重构

    写js也有那么段时间了,也看过几本关于js的书,从最初的<锋利的jquery><高性能javasrcipt>到<javascript设计模式>等,虽然看了些书,看到 ...

  7. 咦,好像可以自己做个webapi框架了-IRouteHandler的使用

    当我们学习到一定程度的时候,我们会想要去深入了解代码底层的东西,也更想拥有一个属于自己的框架,当然,博主也正是如此.本文可能成为编写一个webapi框架的开端.有研究MVC框架的朋友会发现,mvc框架 ...

  8. [UWP]用Shape做动画

    相对于WPF/Silverlight,UWP的动画系统可以说有大幅提高,不过本文无意深入讨论这些动画API,本文将介绍使用Shape做一些进度.等待方面的动画,除此之外也会介绍一些相关技巧. 1. 使 ...

  9. 2个问题,解决tomcat启动一闪而过和运行tomcat/bin目录下的startup.bat时报错(the CATALINA_HOME environment variable is not defined correctly)

    1.除手动使用开始菜单自启动或者程序启动TOMCAT时TOMCAT一闪而过,这时候是发生了错误,这时候我们打开BIN目录下的“startup.bat”文件,编辑,在结尾添加pause命名,这样在CMD ...

  10. 前端程序员的蜕变——JS的 event 对象属性、使用实例、兼容性处理(极大提高代码效率、减少代码量)

    下面讨论一下 js 中的 Event 对象,主要从以下三个方面详细的描述(点击标题可跳转到对应部分): 1.什么是event 2.怎么用event,用他该注意什么,几个简单实际应用 3.event在不 ...