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 ...
随机推荐
- NetFramework各个版本的特性笔记
公式记忆: .Net 2.0=CLR+BCL+C#(VB.Net)+Win Form+Web Form .Net 3.0=.Net 2.0+WCF+WPF+WF+WCS .Net 3.5=.Net 3 ...
- nodeJS之二进制buffer对象
前面的话 在ES6引入TypedArray之前,JavaScript语言没有读取或操作二进制数据流的机制.Buffer类被引入作为Nodejs的API的一部分,使其可以在TCP流和文件系统操作等场景中 ...
- CSS小技巧-为内盒子添加margin-top时,会带着父盒子一起下来,如何解决?
1.为父盒子添加一个padding 2.为父盒子添加一个border 3.为父盒子添加一个overflow:hidden
- Java之FilenameFilter接口
FilenameFilter接口:是用于过滤文件的 要实现的是accept方法 实例代码: 1,匿名类实现FilenameFilter-–过滤指定类型文件 package File类过滤器; impo ...
- PHP初体验
PHP初体验 提笔写初体验总不知道从何说起,直接聊PHP中的函数.PHP网络技术.数据库操作.PHP模板等感觉又不是初体验.最后还是决定从PHP的面向对象.PHP的魔术方法.PHP的反射.PHP中的异 ...
- jdbc的配置及jdbc连接常用数据库(mysql、sqlserver、Oracle)
1.连接SQL Server数据库 import java.sql.*; publicclassMain{publicstaticvoid main(String[] args){String dri ...
- 如何在office2007中插入MathType教学
很多人在安装MathType数学公式编辑器时可能会遇到这个问题,MathType安装好了,可是在office2007的菜单栏中没有MathType这个选项卡,也就是说MathType没有成功加载在of ...
- 水平方向的RecyclerView
最近做了一个项目需要实现一个卡片式的水平滑动,但是不能手势滑动,点击卡片上的按钮之后滑动到下一个卡片,所以想到用RecyclerView实现,去掉它的手势滑动,点击按钮之后再代码控制滑动到下一个卡片. ...
- DDD理论学习系列(7)-- 值对象
DDD理论学习系列--案例及目录 1.引言 提到值对象,我们可能立马就想到值类型和引用类型.而在C#中,值类型的代表是strut和enum,引用类型的代表是class.interface.delega ...
- SpringMVC学习资料
一.SpringMVC 1.helloworld 1.导包 <dependency> <groupId>org.springframework</groupId> ...