linux高并发网络编程开发(xml json)16_xml和Json相关api及文件解析制作

news2024/11/15 5:42:09

pdf详细版

01 学习目标

xml

  • xml基础语法和规范
  • C程序中如何使用xml开源库
  • 借助开源库,在C程序中生成xml文件
  • 已知一个xml文件,如何借助开源库解析xml文件数据

Json

  • json的基础语法和规范
  • C程序中如何使用json开源库 - cjson
  • 使用cjson生成json文件
  • 已知一个json文件,使用cjson库解析文件数据

02 xml文件格式

<!-- 注释 -->
<!-- 文件头 -->
<?xml version="1.0" encoding="UTF-8"?>
<!-- 树状结构的标签 -->
<!-- 根标签 -- 自个起名   只有一个 -->
<!-- 标签的值区分大小写 -->


<!-- 标签一般成对出现 -->
<Zhangsan>
	<!-- 不成对 -->
	<lisi/>
	<!-- 子标签 -->
	<child>
		<!-- 没有子标签, 标签必须有值 -->
		<!-- 标签可以设置属性 report: 属性, 属性值需要使用""包含-->
		<name report="yes">zhang1</name>
		<age yefen="1">12</age>
		<sex>男</sex>
	</child>
	<!-- 子标签 -->
	<child>
		<name>zhang2</name>
		<age>4</age>
		<sex>女</sex>
	</child>
</Zhangsan>

03 xml示例文件

<?xml version="1.0" encoding="utf-8"?>
<car>
	<factory>
		<name>一汽大众</name>
		<brand>
			<name>高尔夫</name>
			<color>红色</color>
			<price>15万</price>
		</brand>
		<brand>
			<name>速腾</name>
			<color>银白</color>
			<price>18万</price>
		</brand>
		<brand>
			<name>迈腾</name>
			<color>黑灰</color>
			<price>28万</price>
		</brand>
	</factory>
	<factory>
		<brand>
			<name>帕萨特</name>
			<color>黑色</color>
			<price>25万</price>
		</brand>
		<brand>
			<name>POLO</name>
			<color>灰色</color>
			<price>8万</price>
		</brand>
	</factory>
</car>

04 xml文件的设计

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<China>
	<City>
		<Name isbig="true">北京</Name>
		<Area>1.641万平方千米</Area>
		<Population>2200万</Population>
	</City>
	<City>
		<Name isbig="false">石家庄</Name>
		<Area>15848平方千米</Area>
		<Population>107万</Population>
	</City>
</China>

05 mxml安装和配置

minixml官网地址
http://www.msweet.org/projects.php/Mini-XML
其他解析xml开源库:tinyxml pugixml
○ 包含头文件: mxml.h
○ 编译的时候需要添加动态库: libmxml.so
▪ -lmxml
▪ /usr/local/lib

  1. minixml安装:
    ○ ./configure --enable-threads=no && make
    ○ sudo make install

  2. 新目录需要一个文件头 - 标准
    ○ <?xml version="1.0" encoding="utf-8"?>
    ○ version不可以省略
    ○ encoding可以省略

  3. 使用注意事项
    ○ 必须有一个根元素(节点) – (只有一个)
    ○ xml标签对大小写敏感
    ○ 标签大多成对使用, 有开始, 有结束

<date></date>
<time></time>
  1. 标签中可以添加属性

    ○ 属性值必须加引号.

  2. 标签注释
    <!-- 这是注释 -->

06 mxml生成文件函数介绍

开源库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
);

07 使用mxml api生成xml文件

xml_create.c:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <mxml.h>

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;
}

08 mxml获取文件数据api

○ 解析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 // 同上
);

09 mxml格式文件解析

parse_xml.c:

#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文件格式

  1. cjson的使用
  • 压缩包解压缩,直接使用里边的cJSON.c和cJSON.h即可
  • 链接时还需要加上-lm 表示链接math库
  1. json的格式
  • 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,
		"孩子":["小红", "小绿", "小黑"]
	}
}

11 json格式示例文件

{
	"奔驰":	{
		"factory":	"一汽大众",
		"last":	31,
		"price":	83,
		"sell":	49,
		"sum":	80,
		"other":	[124, "hello, world", false]
	}
}

12 cjon介绍

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();

13 cjson api创建json文件

将cjson库的cJSON.h和cJSON.c文件复制到目录中
Json_create.c:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#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;
}

14 cjson解析api

○ 解析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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

列存储、行存储

一、定义 1.1定义 Sybase在2004年左右就推出了列存储的Sybase IQ数据库系统,主要用于在线分析、数据挖掘等查询密集型应用。列存储&#xff0c;缩写为DSM&#xff0c;相对于NSM(N-ary storage model)&#xff0c;其主要区别在于&#xff1a; DSM将所有记录中相同字段的数据聚…

【AUTOSAR】BMS开发实际项目讲解(二十三)----电池管理系统高压互锁保护

高压互锁保护 关联的系统需求 TSR-BMS-6101、TSR-BMS-6102、TSR-BMS-6103、TSR-BMS-6104、TSR-BMS-6105、TSR-BMS-6106、TSR-BMS-6107、TSR-BMS-6108、TSR-BMS-6109、TSR-BMS-6110、TSR-BMS-6111; TSR-BMS-6201; TSR-BMS-6301; TSR-BMS-S101、TSR-BMS-S102、TSR-BMS-S103、TS…

AutoSAR系列讲解(入门篇)4.3-BSW的Communication功能

一、架构与术语解释 BSW中以后每一节我都会放上一张模块图&#xff0c;所以就先上图&#xff1a; 由于汽车上一般都使用CAN总线&#xff0c;图中的bus大家可以就当成CAN来看待&#xff0c;如果使用的是LIN或者其他的&#xff0c;也相应的换成其总线看待就行。后续在实践篇中将会…

你需要了解的 50 个 ChatGPT 统计数据和事实

Rest assured that with the ChatGPT statistics you’re about to read, you’ll confirm that the popular chatbot from OpenAI is just the beginning of something bigger. Since its launch in November 2022, ChatGPT has broken unexpected records. For example, it r…

数据结构之串

1.串的基本概念 • 一个串是由n&#xff08;n≥0&#xff09;个字符组成的有限序列&#xff0c;记为s“s0s1 ⋯ sn-1”&#xff0c;其 中&#xff0c;s是串名&#xff0c;双引号括起来的字符序列s0s1 ⋯ sn-1是串值。 • 一个字符在串中的位置称为该字符在串中的序号&#xff…

微搭低代码实现表单打印功能

目录 1 引入第三方库2 搭建页面3 实现打印4 实现效果总结 在我们的日常开发场景中&#xff0c;表单打印是一个比较常见的场景&#xff0c;微搭本身不带打印功能&#xff0c;我们需要借助一个第三方的库来实现打印。 1 引入第三方库 在微搭中如果需要引入第三方库的&#xff0…

阿里云免费云服务器领取教程

阿里云推出了免费试用中心&#xff0c;提供超百款免费试用云产品&#xff0c;个人用户与企业用户均可免费试用&#xff0c;云服务器最长免费体验3个月&#xff01; 一、活动地址 阿里云免费试用中心 二、活动对象 满足以下全部条件的阿里云用户&#xff1a; 1、阿里云注册会…

JS模块化规范及进化史

模块化规范及进化史 按照功能和需求分成各个模块&#xff0c;最后再把所有模块合并在一起。当然现在基于webpack vue/react&#xff0c;模块化开发很重要。某个功能板块单独写成一个模块&#xff0c;然后把模块合在一起&#xff0c;最后把整个页面的功能实现。方便团队管理 小插…

stunnel-加密通道-squid-IP缓存服务器-openssl自签名证书

文章目录 1.安装squid2.管理squid服务3.安装Stunnel服务器端4.安装Stunnel客户端5.在目标使用位置开启代理 1.安装squid yum install squid 2.管理squid服务 systemctl start squid systemctl stop squid systemctl status squid 查看端口 netstat -lntpo | grep 8**** 修改配…

集成增益采样电路误差计算--适用INA214

一、 一般集成电路结构如下&#xff1a; 二、 典型的计算步骤如下&#xff1a; 主要误差来源&#xff1a;采样电阻R-shunt&#xff0c;集成增益运放&#xff0c;ADC误差。 采样电阻误差 误差项包括常温下电阻的精度X1%&#xff0c;电阻的温漂值X2% 误差百分比为&#xff1a;…

《C++ Primer》--学习11

关联容器中的元素是按关键字来保存和访问的 两个主要的关联容器类型是 map 和 set。map 中的一个关键字-值&#xff08;key - value&#xff09;对&#xff1a;关键字起到索引作用&#xff0c;值则表示与索引相关联的数据。set 中每个元素只包含一个关键字&#xff1b; 以下八…

Java-数据结构(一)

这里写目录标题 前言一、为什么需要数据结构&#xff1f;1、低效的操作2、占用过多的内存空间3、困难的数据操作 二、枚举&#xff08;Enumeration&#xff09;1、定义2、关键字3、适用场景 三、 位集合&#xff08;BitSet&#xff09;1、定义2、方法3、适用场景 四、向量&…

文件操作 -- C语言

在之前学习的时候&#xff0c;我们可以发现当程序运行完&#xff0c;我们之前保存的数据就会消失&#xff0c;再次运行时还得重新输入&#xff0c;为了使我们保存的数据在下次运行时还能使用&#xff0c;我们这篇文章来学习一下怎么使用文件操作&#xff0c;将我们的数据保存在…

SQL14 操作符混合运用

select device_id,gender,age,university,gpa from user_profile where university山东大学 and gpa>3.5 or university复旦大学 and gpa>3.8;

Linux 抓包工具——tcpdump

1 简介 用简单的话来定义tcpdump&#xff0c;就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口…

由浅入深探究mysql索引结构原理、性能分析与优化

目录 第一部分&#xff1a;基础知识 第二部分&#xff1a;MYISAM和INNODB索引结构 1、 简单介绍B-tree B tree树 2、 MyisAM索引结构 3、 Annode索引结构 4、 MyisAM索引与InnoDB索引相比较 第三部分&#xff1a;MYSQL优化 1、表数据类型选择 2、sql语句优化 3、系统配置与维护…

Java对称与非对称加密解密(AES与RSA)

尽可能预想所有残酷的可能性、因为现实永远让你无法预警,而且又吝于给人慈悲。——富坚义博 今天我们讨论一下秘钥这个东西 一、对称加密技术与非对称加密技术简述 加密技术可以分为对称与非对称两种。 对称加密、解密即加密与解密用的是同一把秘钥,常用的对称加密技术有DES,A…

MySQL - 连表查询 Join On 详解

1. 连表查询详解 市面上有 7 种连表查询, 总共归为三大类 : 左查询 LEFT JOIN -- 以左表为基准右查询 RIGHT JOIN -- 以右表为基准交叉查询 INNER JOIN -- 查询两表都有的数据 操作描述inner join如果表中至少有一个匹配, 就返回行left join会从左表中返回所有的值…

IDEA 设置文件头的注释信息author,date,description

打开setting设置窗口 file and code Templates 2、编辑Class模版 /*** Author:${USER}* Date:${YEAR}-${MONTH}-${DAY}* Description:TODO* */ 创建一个新JAVA类&#xff0c;测试一下&#xff0c;OK

chatgpt赋能python:如何通过Python赚取外快:SEO技巧分享

如何通过Python赚取外快&#xff1a;SEO技巧分享 作为一名有10年Python编程经验的工程师&#xff0c;我发现Python不仅用来写代码&#xff0c;还可以用来赚取外快。SEO是一个非常赚钱的市场&#xff0c;而Python可以帮助我们更好地优化网站&#xff0c;从而实现更高的排名&…