JSON简介
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
JSON建构于两种结构:
∙ 对象,即“名称/值”对的集合(A collection of name/value pairs)。一个对象可以包含多个“名称/值”对,可以理解为对象的属性。
∙ 数组,值的有序列表(An ordered list of values)。
其中,“名称”是一个字符串,而“值”可以是多种数据类型,包括:字符串、数字、布尔值、null值、对象、数组。由此可见,JSON中数组和对象之间是可以相互嵌套的。一个JSON文档被解释为一个“值”,这个值的类型可以是上面列出的任何类型。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。
JSON具有以下这些形式:
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
字符串(string)与C或者Java的字符串非常相似。
数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
空白可以加入到任何符号之间,但将被解析器过滤掉,不会出现在最终的解析结果中。
Jsoncpp编程接口
Jsoncpp是一个使用C++语言实现的面向对象的json库,以静态库的形式提供,使用非常简单。
Jsoncpp提供的接口中有3个核心类:Reader、Writer、Value。
Reader类负责从字符串或者输入流中加载JSON文档,并进行解析,生成代表JSON文档的Value对象。
Writer类负责将内存中的Value对象转换成JSON文档,输出到文件或者是字符串中。
Value类的对象代表一个JSON值,既可以代表一个文档,也可以代表文档中一个值。如同JSON中定义的“值”一样,Value是递归的。
解析JSON文档
解析一个JSON文档的大致过程如下:
//生命顶级Value对象
Json::Value root;
//读取文档:
Std::string strdoc = readFromFile(…);
//声明Reader对象
Json::Reader _reader;
//解析json文档
_reader.paser(strdoc, root);
//从root中提取数据,基本模式如下函数所示,其中PARAM out只是抽象的占位符,代表用来保存从Value中提取的数据的对象,并不是一个实际实现的类。
GetValueFromTree( PARAM out, Json::Value &value )
{
switch ( value.type() )
{
case Json::nullValue:
out.outvalue("null");
break;
case Json::intValue:
out.outvalue(value.asInt());
break;
case Json::uintValue:
out.outvalue(value.asUInt());
break;
case Json::realValue:
out.outvalue(value.asDouble());
break;
case Json::stringValue:
out.outvalue(value.asString().c_str());
break;
case Json::booleanValue:
break;
out.outvalue(value.asBool());
break;
case Json::arrayValue:
{
int size = value.size();
//数组类型,使用数字下标作为索引遍历所有元素
for ( int index =0; index < size; ++index )
{
python怎么读取json文件 printValueTree( out, value[index] );
}
}
break;
case Json::objectValue:
{
//对象类型,其成员被保存在一个map里面,使用name作为索引进行查
Json::Value::Members members( value.getMemberNames() );
//遍历所有的name,查值
for ( Json::Value::Members::iterator it = members.begin();
it != members.end();
++it )
{
const std::string &name = *it;
printValueTree( out, value[index] );
}
}
break;
default:
break;
}
}
不同定义的JSON文档,保存不同的数据,解析之后的数据也需要使用不同的数据结构来存储。
比如如下结构体:
Struct user
{
Int id;
String name;
Struct
{
Int homeserver;
Int vistserver;
}serverinfo;
Int skillids[3];
};
可使用如下定义的JSON文档表示:
{
“Type”:“USER_INFO”,
“Data”:
{
“id”:1,
“name”:“spring”,
“server”:
{
“homeserver”:1001,
“vistserver”:1003
},
“skillids”:
[
1,2,3
]
}
}
从内存中创建Value对象
在需要将内存数据转换为JSON时就需要从内存中创建一个Value对象,然后再转化为文本进行输出。所以从内存中创建Value对象也是常用的操作,所有需要转化为JSON文档表示的数据结构都需要定义一个toJson成员函数:
Bool toJson(Json::Value& value);
内部实现模式
如果是一个简单的Value值,如布尔、数值、空值、字符串等,则直接使用构造函数创建Value。如:
Value(datatype);
如果要创建一个对象类型的Value,首先使用
Value root(ValueType type = objectValue)
声明一个空的类型为对象的Value对象。
然后使用类似于root[“type”] = “USER_INFO”的表达式,往root中添加属性(key/value对)。
如果要创建一个数组类型的Value,首先使用
Value root(ValueType type = arrayValue)
声明一个空的类型为数组的Value对象。
然后使用root.append(Value&)成员,在数组的末尾追加一个值,或者使用root[index]来访问数组的元素。如果index值超出了当前数组的长度,那么将会在数组末尾追加一个元素,并返回这个元素的引用。
要创建代表如下JSON文档的Value对象:
{
“Type”:“USER_INFO”,
“Data”:
{
“id”:1,
“name”:“spring”,
“server”:
{
“homeserver”:1001,
“vistserver”:1003
},
“skillids”:
[
1,3,5
]
}
}
需要如下代码:
//声明object类型的对象,根对象
Value root(objectValue);
//添加Type属性这里隐含自动类型转换,将string转化为Value
Root[“Type”] = “USER_INFO”;
Value Data(objectValue);//下面创建Data子对象
Data[“id”] = 1;
Data[“name”] = “spring”;
Value _server(objectValue);
_server[“homeserver”] = 1001;
_server[“vistserver”] = 1003;
Data[“server”] = _server;
Value _skillids(objectValue);
_skillids.append(1);
_skillids.append(3);
_skillids.append(3);
Data[“skillids”] = _skillids;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论