来自黑马课程视频
9.xml
minixml官网地址
http://www.msweet.org/projects.php/Mini-XML
其他解析xml开源库:tinyxml pugixml
-
minixml安装:
-
-lmxml
-lpthread
./configure --enable-threads=no && make
sudo make install
-
文件头
<?xml version="1.0" encoding="utf-8"?>
version
不可省略encoding
可以省略
-
注意事项
- 必须有一个根节点 – 且只有一个,就是文件头
- 对大小写敏感
- 标签成对使用
<date></date>
-
标签添加属性
<node date="17/11/2022">
- 属性值必须加
""
-
标签注释
<!-- 注释 -->
-
开源库使用
-
生成xml文件
-
创建一个新的xml文件
mxml_node_t *mxmlNewXML(const char *version);
- 返回新创建的xml文件结点
- 默认的文件编码格式为utf-8
-
删除结点的内存
void mxmlDelete(mxml_node_t *node);
-
添加一个新的结点
mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
parent
父节点name
新节点标签名
-
设置结点的属性值和属性名
void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value);
node
设置属性的结点name
结点的属性名value
结点的属性值
-
创建结点的文本内容
mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
parent
结点地址whitespace
是否有空白0string
文本内容
-
保存结点到xml文件
int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb);
node
根节点fp
文件指针,fopen()
cb
默认MXML_NO_CALLBACK
-
code
#include <stdio.h> #include <mxml.h> int main(int argc, const char* argv[]) { // 创建xml文件头节点 mxml_node_t *xml = mxmlNewXML("1.0"); // 创建xml根节点 - china mxml_node_t* china = mxmlNewElement(xml, "China"); // 创建城市节点 mxml_node_t* city = mxmlNewElement(china, "City"); // 添加子节点 // name mxml_node_t* name = mxmlNewElement(city, "Name"); // 设置标签值 mxmlNewText(name, 0, "北京"); mxmlElementSetAttr(name, "isbig", "true"); // 面积 mxml_node_t* area = mxmlNewElement(city, "Area"); mxmlNewText(area, 0, "1.641万平方千米"); // 人口 mxml_node_t* popu = mxmlNewElement(city, "Population"); mxmlNewText(popu, 0, "2200万"); // 第二个城市节点 city = mxmlNewElement(china, "City"); // name name = mxmlNewElement(city, "Name"); mxmlNewText(name, 0, "石家庄"); mxmlElementSetAttr(name, "isbig", "false"); area = mxmlNewElement(city, "Area"); mxmlNewText(area, 0, "15848平方千米"); popu = mxmlNewElement(city, "Population"); mxmlNewText(popu, 0, "107万"); // 将xml内容保存到磁盘 FILE* fp = fopen("china.xml", "w"); mxmlSaveFile(xml, fp, MXML_NO_CALLBACK); fclose(fp); mxmlDelete(xml); return 0; }
-
-
解析xml文件
-
从文件加载xml到内存
mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, mxml_type_t (*cb)(mxml_node_t *));
top
一般为NULLfp
文件指针cb
默认MXML_NO_CALLBACK
-
获取结点的属性
const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
node
带属性的结点的地址name
属性名
-
获取结点的文本内容
const char *mxmlGetText(mxml_node_t *node, int *whitespace);
-
跳转到下一个结点
mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,int descend);
top
根节点descend
搜索规则MXML_NO_DESCEND
:查看同层级MXML_DESCEND_FIRST
:查看下一层级的第一个MXML_DESCEND
:一直向下搜索
-
查找结点
mxml_node_t *mxmlFindElent(mxml_node_t *node, mxml_node_t *top, const char *name, const char *attr, const char *value, int desend);
node
当前节点top
根节点name
查找的标签名attr
查找的标签的属性value
属性值desend
-
code
#include <stdio.h> #include <mxml.h> 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; }
-
-
10.json
-
使用库
- 压缩包解压缩,直接使用里边的cJSON.c和cJSON.h即可
- 链接时还需要加上-lm 表示链接math库
-
格式
- 数组
- 表示形式:
[1,"2334",true]
- 可以包含:各种数据类型,
char
,int
,bool
,json
数组,json
对象…
- 表示形式:
- 对象
- 表现形式:
{key:value,key1:value}
key
:必须是字符串value
:没有限制…
- 表现形式:
- 数组
-
C语言的开源库 — cjon
-
生成json文件
-
创建json对象
cJSON *cJSON_CreateObject(void);
-
向json对象中添加数据成员
-
void cJSON_AddItemToObject(
cJSON *object, // json对象
const char *string, // key值
cJSON *item // value值(int,string,array,obj)
);`
-
-
创建一个整形值
cJSON *cJSON_CreateNumber(double num);
-
创建一个字符串
cJSON *cJSON_CreateString(const char *string);
-
创建一个json数组
cJSON *cJSON_CreateArray(void);
– 空数组
-
创建默认有count个整型值得json数组
cJSON *cJSON_CreateIntArray(const int *numbers,int count);
int arry[] = {8,3,4,5,6};
cJSON_CreateIntArray(arry, 5);
-
往json数组中添加数据成员
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
-
释放json结构指针
void cJSON_Delete(cJSON *c)
-
将json结构转化为字符串
char *cJSON_Print(cJSON *item);
- 返回值需要使用free释放
FILE* fp = fopen();
fwrite();
fclose();
-
code
#include <stdio.h> #include <string.h> #include "cJSON.h" int main(int argc, const char* argv[]) { // 创建json对象 cJSON* obj = cJSON_CreateObject(); // 创建子对象 - 品牌 cJSON* brand = cJSON_CreateObject(); // 添加键值对 cJSON_AddItemToObject(brand, "factory", cJSON_CreateString("一汽大众")); cJSON_AddItemToObject(brand, "last", cJSON_CreateNumber(31)); cJSON_AddItemToObject(brand, "price", cJSON_CreateNumber(83)); cJSON_AddItemToObject(brand, "sell", cJSON_CreateNumber(49)); cJSON_AddItemToObject(brand, "sum", cJSON_CreateNumber(80)); // 创建json数组 cJSON* array = cJSON_CreateArray(); cJSON_AddItemToArray(array, cJSON_CreateNumber(124)); cJSON_AddItemToArray(array, cJSON_CreateString("hello, world")); cJSON_AddItemToArray(array, cJSON_CreateBool(0)); cJSON_AddItemToObject(brand, "other", array); cJSON_AddItemToObject(obj, "奔驰", brand); // 格式化json对象 char* text = cJSON_Print(obj); FILE* fp = fopen("car.json", "w"); fwrite(text, 1, strlen(text), fp); fclose(fp); return 0; }
-
-
解析json文件
-
将字符串解析为json结构
cJSON *cJSON_Parse(const char *value);
- 返回值需要使用
cJSON_Delete
释放
-
根据键值查找json结点
-
cJSON *cJSON_GetObjectItem(
cJSON *object, // 当前json对象
const char *string // key值
);
-
-
获取json数组中元素得个数
int cJSON_GetArraySize(cJSON *array);
-
判断是否有对应得键值对
int cJSON_HasObjectItem(cJSON *object, const char *string)
-
code
#include <stdio.h> #include <string.h> #include "cJSON.h" int main(int argc, const char* argv[]) { if(argc < 2) { printf("./a.out jsonfile\n"); return 0; } // 加载json文件 FILE* fp = fopen(argv[1], "r"); char buf[1024] = {0}; fread(buf, 1, sizeof(buf), fp); cJSON* root = cJSON_Parse(buf); cJSON* subobj = cJSON_GetObjectItem(root, "奔驰"); // 判断对象是否存在 if( subobj ) { // 获取子对象 cJSON* factory = cJSON_GetObjectItem(subobj, "factory"); cJSON* last = cJSON_GetObjectItem(subobj, "last"); cJSON* price = cJSON_GetObjectItem(subobj, "price"); cJSON* sell = cJSON_GetObjectItem(subobj, "sell"); cJSON* sum = cJSON_GetObjectItem(subobj, "sum"); cJSON* other = cJSON_GetObjectItem(subobj, "other"); // 打印value值 printf("奔驰:\n"); printf(" factory: %s\n", cJSON_Print(factory)); printf(" last: %s\n", cJSON_Print(last)); printf(" price: %s\n", cJSON_Print(price)); printf(" sell: %s\n", cJSON_Print(sell)); printf(" sum: %s\n", cJSON_Print(sum)); // 打印数组内容 printf(" other:\n"); if(other->type == cJSON_Array) { for(int i=0; i<cJSON_GetArraySize(other); ++i) { cJSON* node = cJSON_GetArrayItem(other, i); // 判断数据类型 if(node->type == cJSON_String) { printf(" %s \n", node->valuestring); } if(node->type == cJSON_Number) { printf(" %d\n", node->valueint); } if(node->type == cJSON_True) { printf(" %d\n", node->valueint); } if(node->type == cJSON_False) { printf(" %d\n", node->valueint); } } } } cJSON_Delete(root); fclose(fp); return 0; }
-
-