1、支持按照表名、记录号、JSONPATH从原始数据中提取指定字段的值
2、支持按照表名从原始数据中获取有多少条记录
3、支持按照表名、记录号和JSONPATH从原始数据中获取指定内层json_array的记录数
#include
#include
#include
#include
union type
{
long INT;
int BOOL;
double DOUBLE;
char STRING[100];
json_t* VALUE;
};
struct json_value
{
char json_type[30];//存放json的类型
union type var;//存放json的value
};
struct my_json
{
int num_bottom;//存放指定内层的记录数
json_t* value; //存放定位到的json
};
struct json_count
{
json_t *root;//用于存放从gmdata文件加载的json数据
int count;//用于存放表名最外层的记录数
};
void get_value_by_json(json_t* root,struct json_value* json)//获取json的类型和数据
{
if(root==NULL)
return;
memset((*json).json_type,0,sizeof((*json).json_type));
memset((*json).var.STRING,0,sizeof((*json).var.STRING));
switch(json_typeof(root))
{
case JSON_OBJECT :
{
strncpy((*json).json_type,"JSON_OBJECT",sizeof((*json).json_type));
(*json).var.VALUE=root;
}
break;
case JSON_ARRAY :
{
strncpy((*json).json_type,"JSON_ARRAY",sizeof((*json).json_type));
(*json).var.VALUE=root;
}
break;
case JSON_STRING :
{
strncpy((*json).json_type,"JSON_STRING",sizeof((*json).json_type));
strncpy((*json).var.STRING,json_string_value(root),sizeof((*json).var.STRING));
}
break;
case JSON_INTEGER:
{
strncpy((*json).json_type,"JSON_INTEGER",sizeof((*json).json_type));
(*json).var.INT=json_integer_value(root);
}
break;
case JSON_REAL :
{
strncpy((*json).json_type,"JSON_REAL",sizeof((*json).json_type));
(*json).var.DOUBLE=json_real_value(root);
}
break;
case JSON_TRUE :
{
strncpy((*json).json_type,"JSON_TRUE",sizeof((*json).json_type));
(*json).var.BOOL=1;
}
break;
case JSON_FALSE :
{
strncpy((*json).json_type,"JSON_FALSE",sizeof((*json).json_type));
(*json).var.BOOL=0;
}
break;
case JSON_NULL :
{
printf("json_null\n");
strncpy((*json).json_type,"JSON_NULL",sizeof((*json).json_type));
}
break;
}
}
struct json_count* json_load_by_name(const char* table_name,const char* file_path)
{
struct json_count* json_ret=(struct json_count*)malloc(sizeof(struct json_count));
(*json_ret).root=NULL;
(*json_ret).count=0;
char filename_buf[1024]={0};
strncat(filename_buf,file_path,strlen(file_path));
strncat(filename_buf,"/",1);
strncat(filename_buf,table_name,strlen(table_name));
strncat(filename_buf,".gmdata",strlen(".gmdata"));//获取文件的路径
json_error_t error;
(*json_ret).root=json_load_file(filename_buf,JSON_REJECT_DUPLICATES,&error);//从指定路径文件提取json值
if((*json_ret).root==NULL)
{
printf("json)load_file fail\n");
}
switch(json_typeof((*json_ret).root))
{
case JSON_OBJECT :
{
(*json_ret).count=1;
}
break;
case JSON_ARRAY :
{
(*json_ret).count=json_array_size((*json_ret).root);
}
break;
default:
{
(*json_ret).count=1;
}
break;
}
return json_ret;
}
void string_cut(char* buf,int buf_size,const char*source,char cut)//以字符cut为分隔符,将字符串source进行分割
{
memset(buf,0,buf_size);//buf清零
while(*source!='\0'&&*source!=cut)
{
*buf=*source;
buf++;
source++;
}
*buf='\0';//字符串结束符
}
void get_value_by_jsonpath(json_t* root,const char* json_path,struct my_json* json_ret)
{
/*截取字符串*/
char buf[1024]={0};//用于保存切割出来的字符串
unsigned int len=0;//记录从哪里开始截取
json_t *ret=root;
while(len<=strlen(json_path))
{
string_cut(buf,sizeof(buf),json_path+len,'.');//字符串切割,获得键值key或表示数组的字符串
//printf("%s\n",buf);
void* iter=json_object_iter_at(ret,buf);//假设buf是键值key
if(iter!=NULL)//键值key能找到,则截取下个键值key,并继续上一步,即继续往下找
{
ret=json_object_iter_value(iter);
if(ret==NULL)
printf("json_object_iter_value failed\n");
}
else//键值对没找到(可能是数组表示形式,也可能成员不存在)
{
char buf1[1024]={0};//用于存储数组元素的键值
int index=0;//用于存储数组的index
char* position1=strrchr(buf,'[');//确定[最后次出现的位置
char* position2=strchr(buf,']');//确定]最后次出现的位置
if(position1>=position2-1||position1==NULL||position2==NULL)//判断“[]”出现形式正确
{
printf("the json_path is error");
(*json_ret).value=NULL;//*
return;//*
//return NULL;
}
char *tmp=position1;
for(++position1;position1'9'||*position1<'0')
{
printf("the json_path is error");
{
(*json_ret).value=NULL;//*
return;//*
}
//return NULL;
}
index=10*index+(*position1-'0');
}
for(int i=0;buf+iindex)//判断是否为数组json并且数组长度是否符合要求
ret=json_array_get(array,index);//获取数组array第index个元素
}
if(ret==NULL)//到当前路径已找不到,则不用继续查找
{
(*json_ret).value=NULL;//*
return;//*
}
//return NULL;
len+=strlen(buf)+1;//到当前路径能找到,则继续截取key或者数组名
}
//获取内层的记录数
if(ret==NULL)
(*json_ret).num_bottom=0;
else if(json_is_array(ret))
(*json_ret).num_bottom=json_array_size(ret);
else
(*json_ret).num_bottom=1;
(*json_ret).value=ret;//*
}
struct my_json* get_value(json_t* root,int rd_id,const char* json_path)//
{
struct my_json* json_ret=(struct my_json*)malloc(sizeof(struct my_json));
(*json_ret).num_bottom=0;
(*json_ret).value=NULL;
//json_t* ret=NULL;
switch(json_typeof(root))
{
case JSON_OBJECT :
{
if(rd_id>=1)
{
printf("the rd_id of object only is zero\n");
break;//测试一下
}
get_value_by_jsonpath(root,json_path,json_ret);
}
break;
case JSON_ARRAY :
{
int array_size=json_array_size(root);
if(rd_id>=array_size)
{
printf("The record number is too large.\n");
return json_ret;
}
json_t* record=json_array_get(root,rd_id);//获取第rd_id条记录
if(record==NULL)
{
printf("get %dth record failed\n",rd_id);
return json_ret;
//break;
}
get_value_by_jsonpath(record,json_path,json_ret);
}
break;
default:
{
printf("只有一条最简单记录,rd_id和json_path为无效参数\n");
(*json_ret).value=root;
return json_ret;
}
break;
}
return json_ret;
}
int main ()
{
//get_value("fib_main",0,"123.7.541");
//json_t* value=get_value("fib_main",0,"destination_prefix");
//json_ret=get_value("fib_main",1,"fib_alias.fib_info.fib_nh[2].nh_scope");
struct json_count *root=json_load_by_name("fib_main","/root/zhuanghao/jansson-2.5/jshon-20120914");
struct my_json *json_ret=NULL;
json_ret=get_value((*root).root,0,"fib_alias.fib_info.fib_nh[7].nh_oif");
//json_ret=get_value("gmdata",0,"array22.array12[2]");
if((*json_ret).value==NULL)
printf("get_value fail\n");
printf("top=%d\n",(*root).count);
printf("bottom=%d\n",(*json_ret).num_bottom);
struct json_value jvalue;
get_value_by_json((*json_ret).value,&jvalue);
printf("%ld\n", jvalue.var.INT);
printf("%f\n", jvalue.var.DOUBLE);
printf("%s\n",jvalue.json_type);
printf("%s\n",jvalue.var.STRING);
printf("%s\n",jvalue.var.STRING);
if(root!=NULL)
{
free(root);
root=NULL;
}
if(json_ret!=NULL)
{
free(json_ret);
json_ret=NULL;
}
}