我长话短说:
http://download.csdn.net/detail/rongxiaojun/6859823
从官网下的最新的libjson 在centOS 6.4下使用各种错误,“undifined reference to JSONNode”等。
上面是我经过修改后的库文件,解压后两文件:libjson.a 和 libjson.tar.bz2,把静态库libjson.a放到库文件默认路径/lib/或者/usr/lib/下,然后输入命令:ldconfig。
libjson.tar.bz2解压后是名为libjson的目录,里面是libjson.a需要的头文件,把整个libjson连带目录放到头文件默认路径/usr/local/include/下。
2014.2.14 下午四点半左右出现重大突破:
a.libjson_7.6.1.zip 解压后vim JSONOptions.h,注释掉#define JSON_LIBRARY。
b.make后生成libjson.a库文件,将libjson.a加到系统库目录下。
c.回到上级目录,将整个libjson文件夹复制到系统头文件目录下。
unzip libjson_7.6.1
cd libjson
vim JSONOptions.h
注释掉#define JSON_LIBRARY
make
mv libjson.a /usr/local/lib
make clean
cd ..
cp -r libjson /usr/local/include
至此libjson::is_valid及一切应用均步入正轨。
libjson直观图:
对应json字符串:
{
"childA" : "rong",
"childB" : 144,
"childC" :{
"name" : "bastard",
"age" : 26,
"sex" : "female",
"schoolID" : [
7728,
5241
]
}
}
{}内一个逗号分隔开的就是一个节点,这个节点的类型由该节点名字及冒号后面的值决定:“”即为字符串节点,整数即为整数节点,{}即为节点节点,[]即为数组节点。
2014.2.15 下午三点:
a.进入libjson目录下,vim JSONOptions.h,注释掉#define JSON_LIBRARY #define JSON_SAFE #define JSON_STREAM #define JSON_VALIDATE,make生成libjson.a,mv libjson.a /usr/local/lib,cd ..,cp -r libjson /usr/local/include/。编译g++ libjson.cpp -o test -ljson,报is_valid不是libjson成员的错误。
b.vim /usr/local/include/libjson/JSONOptions.h,对JSON_SAFE,JSON_STREAM,JSON_VALIDATE取消注释。编译g++ libjson.cpp -o test -ljson,报JSONValidator::isValidRoot(char const*)未定义的错误,这正是对http://download.csdn.net/detail/rongxiaojun/6859823现成库仅修改头文件然后编译libjson.cpp遇到的问题。
至此得出结论:JSONOptions.h中的define决定了哪些文件会被编译进库文件libjson.a,如果一开始没有将validate部分的.cpp文件编译进libjson.a,后期想仅通过修改/usr/local/include/libjson/JSONOptions.h使用validate的功能就会出现函数未定义的错误。
libjson(C++)是以node形式管理数据的:
{
"RootA" : "Value1",
"RootB " : "Value2",
"RootC" : {
"ChildA" : "String",
"ChildB" : 42
}
}
下面的图不好,可以不看。
对应图如下:
JSON由key:value组成,key对应节点名字,value对应节点值。图中方块内是节点名字,椭圆内是节点的值。
根节点有三个孩子,三个孩子名字为:RootA、RootB、RootC,类型分别为JSON_STRING、JSON_STRING、JSON_NODE,三儿子RootC又是节点类型,旗下还有两孙子:ChildA、ChildB,类型分别为JSON_STRING、JSON_NUMBER,值分别为“String”和42。
1.按上图构造JSON结构:
JSONNode n(JSON_NODE);
n.push_back(JSONNode("RootA", "Value1"));
n.push_back(JSONNode("RootB", "Value2"));
JSONNode c(JSON_NODE);
c.set_name("RootC");
c.push_back(JSONNode("ChildA", "String"));
c.push_back(JSONNode("ChildB", 42));
n.push_back(c);
2.访问其中某个节点的值,两种方式[]或者.at(n):
取出二儿子的值:
std::cout<
取出一个叫“ChildB”的孙子的值:
std::cout<
把大儿子的值改为bool型的true:
n["RootA"] = true;
n.at(0) = true;
此时调用
std::cout<
输出为3. 正确,因为:
node的类型分五种:
JSON_NULL 0 //空节点或者说NULL
JSON_STRING 1
JSON_NUMBER 2
JSON_BOOL 3
JSON_ARRAY 4
JSON_NODE 5
调用
std::cout<
输出为5.
唯一需要注意的是:取值即取副本
JSONNode x = n[2].as_node();
x[0] = "hello";
std::cout<
输出:hello String; x只是完整的复制了n的小儿子和他的两个孙子节点。
std::cout<
输出为3 返回调用节点的儿子个数,不计孙子。(2014.2.12 15:05追加)返回数组元素个数。
3.字符串解析为JSON:
std::string json = "{\"RootA\":\"Value1\",\"RootB\":\"Value2\",\"RootC\":{\"ChildA\":\"String\",\"ChildB\":42}}";
JSONNode n = libjson::parse(json);
自动生成上图中的结构,n即为跟节点。parse会在栈上分配空间,所以不要试图释放n的空间。
4.JSON转化为字符串:
std::string jc = n.write_formatted();
std::cout << jc << std::endl;
n为任意节点,write_formatted()会将以n为根节点的JSON结构自动转变为字符串,以上图为例,若n为3中构造的节点,输出为:
{
"RootA" : "Value1",
"RootB" : "Value2",
"RootC" : {
"ChildA" : "String",
"ChildB" : 42
}
}
这里可以使用write()替换write_formatted(),使用write()则输出为:
{ "RootA" : "Value1","RootB" : "Value2", "RootC" : {"ChildA" : "String","ChildB" : 42}}
先写这么多,已经足够你操作JSON了,等想到了什么再添加吧。
5.遍历JSON 树:
std::string json = "{\"RootA\":\"Value in parent node\",\"ChildNode\":{\"ChildA\":\"String Value\",\"ChildB\":42}}";
JSONNode n = libjson::parse(json);
ParseJSON(n);
void ParseJSON(const JSONNode & n){
JSONNode::const_iterator i = n.begin();
while (i != n.end()){
// recursively call ourselves to dig deeper into the tree
if (i -> type() == JSON_ARRAY || i -> type() == JSON_NODE){
ParseJSON(*i);
}
// get the node name and value as a string
std::string node_name = i -> name();
// find out where to store the values
if (node_name == "RootA"){
rootA = i -> as_string();
}
else if (node_name == "ChildA"){
childA = i -> as_string();
}
else if (node_name == "ChildB")
childB = i -> as_int();
//increment the iterator
++i;
}
}
6.
std::string json = "{\"RootA\":\"Value in parent node\",\"ChildNode\":{\"ChildA\":\"String Value\",\"ChildB\":42}}";
JSONNode m = libjson::parse(json);
JSONNode::iterator it = m.find("RootA");
if(it == m.end()) std::cout<<"no the child"<as_string()<
find函数在以m为根节点的json树上查找名字为“RootA”的儿子节点。
end函数返回m最后一个儿子节点的下一个,标示结束。
m.find("ChildA") 则输出"no the child",因为只找儿子不找孙子。
7.
bool libjson::is_valid(string json)至今不能使用。(于2.14被攻破)
8.
#define JSON_NULL '\0'
#define JSON_STRING '\1'
#define JSON_NUMBER '\2'
#define JSON_BOOL '\3'
#define JSON_ARRAY '\4'
#define JSON_NODE '\5'
这就是std::cout<
9.
JSONNode n(JSON_NODE);
n.push_back(JSONNode("RootA", "Hello World"));
JSONNode c(JSON_ARRAY);
c.set_name("ArrayOfNumbers");
c.push_back(JSONNode("", 16));
c.push_back(JSONNode("", 42));
c.push_back(JSONNode("", 128));
n.push_back(c);
printf("the result is : %d %d\n",n[1][0].type(),n[1][0].as_int());
数组即一棵无名孩子树,通过n[i][j]穿层访问适用于子孙及数组。
对应字符串:
{"RootA":"Hello World","ArrayOfNumbers":[16,42,256]}
直观表示:
{
"RootA" : "Hello World",
"ArrayOfNumbers" : [
16,
42,
256
]
}
10.
JSONNode n(JSON_NODE);
n.set_name("2");
std::cout<
设置节点名字,取节点名字。
11.
std::string ss = "{\"ChildNode\":{\"ChildA\":\"String Value\",\"ChildB\":42}}";
JSONNode p = libjson::parse(ss);
std::string child1name = p[0].name();
std::cout<<"child 1 name is "<
查看第N个孩子的名字。
12.若节点n是数字类型且123,n.as_string()正常输出123。
13.
JSONNode a(JSON_NODE);
a.push_back(JSONNode("name","idex"));
JSONNode b(JSON_NODE);
b.push_back(a);
b此时的结构为:
{
"" : {
"name" : "idex"
}
}
14.节点名必须是字符串,值可以为数字
n.push_back(JSONNode(14,25.6));是不可以的,14对应的是节点名,只能是字符串。
15.值的类型决定节点的类型:
比如说n.push_back(JSONNode(“14”,25.6));n有个孩子叫"14",这个孩子存的值是浮点数,决定了这个孩子节点是JSON_NUMBER型的。
在此再次强调,type()可以查看节点类型,但是返回值是不可显示字符,分别为'\0','\1', '\2', '\3'等等,需要(int)强制转换再看。
2014.02.25 21:30又着了道了。
16.取浮点数,以15为例
float f = n["14"].as_float();
17.
JSONNode n:
{
"RootA" : "Hello World",
"num" : "200800300187",
"ArrayOfNumbers" : [
16,
42,
128
],
"hour:01" : 24.7,
"hour:03" : 21.4
}
然后:
JSONNode in;
in.set_name("i am tired");
in.push_back(n["RootA"]);
in.push_back(n[1]);
std::string str = in.write_formatted();
std::cout<
输出:
{
"RootA" : "Hello World",
"num" : "200800300187"
}
18.libjson下有编码问题:
字符串---->parse---->JSONNode---->write---->正常;
push_back(JSONNode("汉字","汉字"))---->write---->字符串中的汉字变成\u00XX;
push_back(JSONNode("汉字","汉字"))---->n["汉字"].as_string()---->正常;
加入下面两个函数:
void UTF8(std::string& obj){
int count = 0;
size_t index = 0;
while((index = obj.find("\\u00", index)) != std::string::npos){
count++;
index++;
}
char ch[count+1];
index = 0;
std::string substr;
for(int i = 0; i < count; i++){
index = obj.find("\\u00", index);
index += 4;
substr = obj.substr(index, 2);
ch[i] = strtol(substr.c_str(), NULL, 16);
}
ch[count] = '\0';
obj = ch;
}
void decode(std::string& obj){
size_t beg = 0;
std::string substr;
while((beg = obj.find("\\u00", 0)) != std::string::npos){
substr = obj.substr(beg, 18);
UTF8(substr);
obj.replace(beg, 18, substr);
}
}
{"device_name":"测试中文","sex":"男","work":"宇宙总司令","object":"打过银河系,解放全宇宙"}
没有经过decode的str,输出为:
{"device_name":"\u00E6\u00B5\u008B\u00E8\u00AF\u0095\u00E4\u00B8\u00AD\u00E6\u0096\u0087","sex":"\u00E7\u0094\u00B7","work":"\u00E5\u00AE\u0087\u00E5\u00AE\u0099\u00E6\u0080\u00BB\u00E5\u008F\u00B8\u00E4\u00BB\u00A4","object":"\u00E6\u0089\u0093\u00E8\u00BF\u0087\u00E9\u0093\u00B6\u00E6\u00B2\u00B3\u00E7\u00B3\u00BB\u00EF\u00BC\u008C\u00E8\u00A7\u00A3\u00E6\u0094\u00BE\u00E5\u0085\u00A8\u00E5\u00AE\u0087\u00E5\u00AE\u0099"}
libjson在windows下的使用
1.前期准备
a.下载libjson_7.6.1.zip,地址:http://sourceforge.net/projects/libjson/files/?source=navbar
解压得到libjson_7.6.1,进入libjson_7.6.1,里面是名为libjson目录。
b. libjson、libjson/_internal/Source、libjson/_internal/Source/JSONDefs,将三个目录下以”._“开头和以”~“结尾的文件全删了。
c.进入libjson/JSONOptions.h
注释掉#define JSON_LIBRARY;
若VS2010处于Debug模式,则取消#define JSON_DEBUG注释。若VS2010处于Release模式,则无需取消。
至此前期准备完成。
2. 开始配置
a. 将libjson目录添加到项目目录。
b. 将libjson目录添加到工程中:
libjson目录添加JSONOptions.h、libjson.h、_internal目录;
_internal目录下添加Source目录;
Source目录下添加JSONDefs目录和Source下所有文件。
JSONDefs目录下添加JSONDefs所有文件。
c. 项目->属性->配置属性->VC++ 目录->包含目录->添加项目目录中libjson路径,如E:\projects\qt5\qt5\libjson
3.使用
引入头文件后就开始使用
#include "libjson/libjson.h"
#include "libjson/JSONOptions.h"