pdf详细版
xml
- xml基础语法和规范
- C程序中如何使用xml开源库
- 借助开源库,在C程序中生成xml文件
- 已知一个xml文件,如何借助开源库解析xml文件数据
Json
- json的基础语法和规范
- C程序中如何使用json开源库 - cjson
- 使用cjson生成json文件
- 已知一个json文件,使用cjson库解析文件数据
zhang1
12
男
zhang2
4
女
一汽大众
高尔夫
红色
15万
速腾
银白
18万
迈腾
黑灰
28万
帕萨特
黑色
25万
POLO
灰色
8万
北京
1.641万平方千米
2200万
石家庄
15848平方千米
107万
minixml官网地址
http://www.msweet.org/projects.php/Mini-XML
其他解析xml开源库:tinyxml pugixml
○ 包含头文件: mxml.h
○ 编译的时候需要添加动态库: libmxml.so
▪ -lmxml
▪ /usr/local/lib
minixml安装:
○ ./configure --enable-threads=no && make
○ sudo make install
新目录需要一个文件头 - 标准
○
○ version不可以省略
○ encoding可以省略
使用注意事项
○ 必须有一个根元素(节点) – (只有一个)
○ xml标签对大小写敏感
○ 标签大多成对使用, 有开始, 有结束
标签中可以添加属性
○
○ 属性值必须加引号.
标签注释
○
开源库minixml的使用
○ 跟标签的对应的节点, 父亲节点是: 文件头节点
○ 生成xml文件
1.创建一个新的xml文件
mxml_node_t *mxmlNewXML(const char *version);
□ 返回新创建的xml文件节点.
□ 默认的文件的编码为utf8
2.删除节点的内存
void mxmlDelete(mxml_node_t *node);
3.添加一个新的节点
mxml_node_t *mxmlNewElement(
mxml_node_t *parent, // 父节点
const char *name // 新节点标签名
);
4.设置节点的属性名和属性值
void mxmlElementSetAttr(
mxml_node_t *node, // 被设置属性的节点
const char *name, // 节点的属性名
const char *value // 属性值
);
5.创建节点的文本内容
mxml_node_t *mxmlNewText (
mxml_node_t *parent, // 节点地址
int whitespace, // 是否有空白 0
const char *string // 文本内容
);
6.保存节点到xml文件
int mxmlSaveFile(
mxml_node_t *node, // 根节点
FILE *fp, // 文件指针
mxml_save_cb_t cb // 默认MXML_NO_CALLBACK
);
xml_create.c:
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char* argv[])
{
// 文件头
mxml_node_t *root = mxmlNewXML("1.0");
// 根标签 -- china
mxml_node_t* china = mxmlNewElement(root, "china");
// 子标签 -- city
mxml_node_t* city = mxmlNewElement(china, "city");
mxml_node_t* info = mxmlNewElement(city, "name");
// 标签赋值
mxmlNewText(info, 0, "北京");
// 设置属性
mxmlElementSetAttr(info, "isbig", "Yes");
// 面积
info = mxmlNewElement(city, "area");
mxmlNewText(info, 0, "16410 平方公里");
// 人口
info = mxmlNewElement(city, "population");
mxmlNewText(info, 0, "2171万人");
// gdp
info = mxmlNewElement(city, "gdp");
mxmlNewText(info, 0, "24541亿元");
// 东京
city = mxmlNewElement(china, "city");
info = mxmlNewElement(city, "name");
// 标签赋值
mxmlNewText(info, 0, "东京");
// 设置属性
mxmlElementSetAttr(info, "isbig", "No");
// 面积
info = mxmlNewElement(city, "area");
mxmlNewText(info, 0, "2188 平方公里");
// 人口
info = mxmlNewElement(city, "population");
mxmlNewText(info, 0, "3670万人");
// gdp
info = mxmlNewElement(city, "gdp");
mxmlNewText(info, 0, "31700亿元");
// 数据保存到磁盘文件
FILE* fp = fopen("china.xml", "w");
mxmlSaveFile(root, fp, MXML_NO_CALLBACK);
fclose(fp);
mxmlDelete(root);
return 0;
}
○ 解析xml文件
1.从文件加载xml到内存
mxml_node_t *mxmlLoadFile(
mxml_node_t *top, // 一般为NULL
FILE *fp, // 文件指针
mxml_type_t (*cb)(mxml_node_t *) // 默认MXML_NO_CALLBACK
);
2.获取节点的属性
const char *mxmlElementGetAttr(
mxml_node_t *node, // 带属性的节点的地址
const char *name // 属性名
);
3.获取指定节点的文本内容
const char *mxmlGetText(
mxml_node_t *node, // 节点的地址
int *whitespace // 是否有空格
);
4.跳转到下一个节点
mxml_node_t *mxmlWalkNext(
mxml_node_t *node, // 当前节点
mxml_node_t *top, // 根节点
int descend
);
descend:搜索的规则
MXML_NO_DESCEND:查看同层级
MXML_DESCEND_FIRST:查看下一层级的第一个
MXML_DESCEND:一直向下搜索
5.查找节点
mxml_node_t *mxmlFindElement(
mxml_node_t *node, // 当前节点
mxml_node_t *top, // 根节点
const char *name, // 查找的标签名
没有属性传NULL
const char *attr, // 查找的标签的属性
const char *value, // 查找的标签的属性值
int descend // 同上
);
parse_xml.c:
#include
#include
int main(int argc, const char* argv[])
{
// 从磁盘加载xml文件
FILE* fp = fopen("china.xml", "r");
if(fp == NULL)
{
printf("fopen error\n");
return 0;
}
// root 节点指向xml文件头
mxml_node_t* root = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
// 遍历 - 取出各个节点的值
// 找到第一个城市节点
mxml_node_t* city = mxmlFindElement(root, root, "City", NULL, NULL, MXML_DESCEND);
if(city == NULL)
{
printf("xml node not found\n");
return 0;
}
while( city )
{
printf("==================\n");
// 向下走一个节点
mxml_node_t* node = mxmlWalkNext(city, root, MXML_DESCEND_FIRST);
printf("city: \n");
printf(" name = %s\n", mxmlGetText(node, NULL));
//
node = mxmlWalkNext(node, root, MXML_NO_DESCEND);
printf(" area = %s\n", mxmlGetText(node, NULL));
//
node = mxmlWalkNext(node, root, MXML_NO_DESCEND);
printf(" population = %s\n", mxmlGetText(node, NULL));
// 搜索下一个城市节点
city = mxmlFindElement(city, root, "City", NULL, NULL, MXML_DESCEND);
}
fclose(fp);
mxmlDelete(root);
return 0;
}
json数组
○ char array[23] = “slkjflajslfd”; - c
○ 中括号[整形, 字符串, 布尔类型, json数组, json对象]
○ [123, 123.2, true, false, [12, 34, 56, “hello, world”]]
json对象
{}中是一些键值对
▪ {
“name”:“zhang3”,
“name2”:“li4”
}
▪ key值: 必须是 字符串, 不重复
▪ value值: json对象, json数组, 布尔, 整形, 字符串
json数组+json对象
{
"name":"zhang3",
"name2":"li4",
"张三":{
"别名":"老王",
"性别":"男",
"年龄":34,
"孩子":["小红", "小绿", "小黑"]
}
}
{
"奔驰": {
"factory": "一汽大众",
"last": 31,
"price": 83,
"sell": 49,
"sum": 80,
"other": [124, "hello, world", false]
}
}
C语言json开源解析库 - cjson
○ 生成json文件
1.创建一个json对象
cJSON *cJSON_CreateObject(void);
2.往json对象中添加数据成员
void cJSON_AddItemToObject(
cJSON *object, // json对象
const char *string, // key值
cJSON *item // value值(int,string,array,obj)
);
3.创建一个整型值
cJSON *cJSON_CreateNumber(double num);
4.创建一个字符串
cJSON *cJSON_CreateString(const char *string);
5.创建一个json数组
cJSON *cJSON_CreateArray(void); -- 空数组
6.创建默认有count个整形值的json数组
cJSON *cJSON_CreateIntArray(const int *numbers,int count);
▪ int arry[] = {8,3,4,5,6};
▪ cJSON_CreateIntArray(arry, 5);
7.往json数组中添加数据成员
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
8.释放jSON结构指针
void cJSON_Delete(cJSON *c)
9.将JSON结构转化为字符串
char *cJSON_Print(cJSON *item);
▪ 返回值需要使用free释放
▪ FILE* fp = fopen();
▪ fwrite();
▪ fclose();
将cjson库的cJSON.h和cJSON.c文件复制到目录中
Json_create.c:
#include
#include
#include
#include
#include
#include
#include "cJSON.h"
int main(int argc, const char* argv[])
{
// 创建对象
cJSON* obj = cJSON_CreateObject();
// 创建子对象
cJSON* subObj = cJSON_CreateObject();
// 添加key-value
cJSON_AddItemToObject(subObj, "factory", cJSON_CreateString("一汽大众"));
cJSON_AddItemToObject(subObj, "last", cJSON_CreateNumber(31));
cJSON_AddItemToObject(subObj, "price", cJSON_CreateNumber(83));
cJSON_AddItemToObject(subObj, "sell", cJSON_CreateNumber(49));
cJSON_AddItemToObject(subObj, "sum", cJSON_CreateNumber(80));
// 创建json数组
cJSON* array = cJSON_CreateArray();
// array添加元素
cJSON_AddItemToArray(array, cJSON_CreateNumber(123));
cJSON_AddItemToArray(array, cJSON_CreateBool(1));
cJSON_AddItemToArray(array, cJSON_CreateString("hello, world"));
// 数组中的对象
cJSON* subsub = cJSON_CreateObject();
cJSON_AddItemToObject(subsub, "梅赛德斯奔驰",
cJSON_CreateString("心所向, 持以恒"));
cJSON_AddItemToArray(array, subsub);
cJSON_AddItemToObject(subObj, "other", array);
// obj中添加key - value
cJSON_AddItemToObject(obj, "奔驰", subObj);
// 数据格式化
char* data = cJSON_Print(obj);
FILE* fp = fopen("car.json", "w");
fwrite(data, sizeof(char), strlen(data)+1, fp);
fclose(fp);
return 0;
}
○ 解析json文件
1.将字符串解析为JSON结构
cJSON *cJSON_Parse(const char *value);
▪ 返回值需要使用cJSON_Delete释放
2.根据键值查找json节点
cJSON *cJSON_GetObjectItem(
cJSON *object, // 当前json对象
const char *string // key值
);
3.获取json数组中元素的个数
int cJSON_GetArraySize(cJSON *array);
4.根据数组下标找到对应的数组元素
cJSON *cJSON_GetArrayItem(cJSON *array, int index);
5.判断是否有可以值对应的键值对
int cJSON_HasObjectItem(cJSON *object, const char *string)