16.xml和json生成和解析 C++/Linux-2022-11-01

xml和json生成和解析


来自黑马课程视频

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 是否有空白0
          • string 文本内容
      • 保存结点到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 一般为NULL
          • fp 文件指针
          • 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;
        }
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值