# fastxml **Repository Path**: microcolin/fastxml ## Basic Information - **Project Name**: fastxml - **Description**: 纯C编写的XML解析引擎 - **Primary Language**: C - **License**: BSD-3-Clause-Clear - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 27 - **Created**: 2024-04-19 - **Last Updated**: 2024-04-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # fastxml 纯C语言编写的XML解析库 # ## 什么是fastxml? ## **fastxml是一款支持XML解析的多根节点的解析引擎,支持特性如下:** - 支持多根 **XML**,一个 **XML** 文档支持多个 ROOT 标记,如下包含`information` 和 `list`: ```xml Josin 26
Changsha
Linux v5.0.1 Git ``` - 支持**单一元素直接闭合**语法 ```xml Josin 26
Changsha
``` - 支持XML文档声明,声明必须位于第一行,以及众多属性,标准的XML声明如下: ```xml ``` - **支持标记的属性特性**,如下面的 `information` 标记包含的 `id` 和 `pid` 属性: ```xml Josin 26
Changsha
``` - 支持**注释**,**注意:注释不可以嵌套** ```xml 2
Changsha
``` - 支持 **CDATA标记** 防止浏览器转义 ```xml
Hunan
``` - 暂不支持特性:**DTD规则以及校验** ## 编译 & 运行 ## **fastxml** 使用纯C99语法编写,可以使用在支持标准C99的操作系统上,**fastxml**使用 cmake编译管理系统,推荐版本 3.13以及以上 ```c git clone https://gitee.com/josinli/fastxml.git cd fastxml mkdir build cd build cmake .. && make ./fastxml ``` ## 性能测试 ## 性能测试基准平台:**MacBook Pro** ,**Linux** 平台性能更高, 解析大约22KB 的 XML 文档 1100 次耗时 1 秒 ## APIs 列表 - 从字符串解析 **XML**,返回 **NULL** 表示XML文件格式错误 ```c CXML *new_cxml_from_string2(char *str, unsigned long long); ``` - 从CXML中编码为字符串,返回的字符串需要通过 **free** 函数释放 ```c char *new_string_from_cxml(CXML *c); ``` - 获取解码 XML 的错误信息 ```c char *new_cxml_get_error(); ``` - 生成CXML对象 ```c CXML *cxml_new_cxml(char *tag, char *version, char *encoding); ``` - 给CXML对象添加根节点 ```c int cxml_add_root_node(CXML *xml, CXML_NODE *node); ``` - 生成CXML节点信息 ```c CXML_NODE *cxml_make_node(char *name, unsigned long nlen, char *text/*可以为NULL*/, unsigned long tlen/*可以为0*/); ``` - 给CXML节点添加属性 ```c int cxml_node_add_attr(CXML_NODE *cnode, char *key, unsigned long klen, char *val, unsigned long vlen); ``` - 给CXML节点添加节点 ```c int cxml_node_add_node(CXML_NODE *cnode, CXML_NODE *snode); ``` - 释放编码后的 **CXML** 信息 ```c int trash_cxml(CXML *v); ``` ### 快捷操作宏 ### **操作节点的宏:** ```c // 用来定义一个 CXML_n 的结构来存储解码后的XML信息 CXML_FIELD_DEF(n) // 中间使用 *aname 来定义一个节点名称, 前面的 * 不能省略 CXML_FIELD_DEF_END(n); ``` ```c // 用来声明函数,用来在其他的文件引入声明 CXML_FIELD_FUNC_DEF(n); ``` ```c // 上面的声明的实现文件 CXML_FIELD_FUNC(n) // 存在多个节点,信息,就定义多行 // 第一个参数对应 XML的节点名称,大小写区分 // 第二个参数对应上面第一步 CXML_FIELD_DEF(n) 中定义的名称,去掉前缀 * // 第三个参数对应第一个参数的字符个数 // 第四个参数可选 if 或者 elif 第一行必须为 if CXML_FIELD_CMP(name, aname, l, e) // 索引位置探头 // 第一个参数为 CXML_FIELD_DEF中定义的名称 // 第二个参数为 xml文件中处于父节点中子节点的索引位置,从零开始 // 第三个参数可选 if 或者 elif 第一行必须为if CXML_FIELD_INDEX_CMP(aname, ik, e) CXML_FIELD_FUNC_END(); ``` 操作节点属性的宏: ```c // 用来定义一个 CXML_n 的结构来存储解码后的XML信息 CXML_ATTR_DEF(n) // 中间使用 *aname 来定义一个节点名称, 前面的 * 不能省略 CXML_ATTR_DEF_END(n); ``` ```c // 用来声明函数,用来在其他的文件引入声明 CXML_ATTR_FUNC_DEF(n); ``` ```c // 上面的声明的实现文件 CXML_ATTR_FUNC(n) // 存在多个节点,信息,就定义多行 // 第一个参数对应 XML的节点名称,大小写区分 // 第二个参数对应上面第一步 CXML_FIELD_DEF(n) 中定义的名称,去掉前缀 * // 第三个参数对应第一个参数的字符个数 // 第四个参数可选 if 或者 elif 第一行必须为 if CXML_ATTR_CMP(name, aname, l, e) // 索引位置探头 // 第一个参数为 CXML_FIELD_DEF中定义的名称 // 第二个参数为 xml文件中处于父节点中子节点的索引位置,从零开始 // 第三个参数可选 if 或者 elif 第一行必须为if CXML_ATTR_INDEX_CMP(aname, ik, e) CXML_ATTR_FUNC_END(); ``` **两种宏的区别**在于第二个单词是 **ATTR** 或者 **FIELD** 如果**需要遍历某一个节点下的所有子节点**,可以使用如下宏: ```c // 第一个参数为父节点的 data 属性 // 第二个参数为自定义的 CXML_NODE 元素的指针 CXML_LOOP_FREACH_DATA(data, cnode) { // 这里访问 cnode 元素内容即可 // printf("%s:%s\n", cnode->key->s, cnode->sval->s); }CXML_LOOP_FOREACH_END() ``` **遍历某一个子节点的所有的属性**信息,使用如下宏: ```c // 第一个参数为需要遍历属性节点的 attrs // 第二个参数为自定义的 CXML_ATTR 元素的指针 CXML_LOOP_FREACH_ATTR(attrs, attr) { // 这里访问 attr 属性即可 printf("\t%s:%s\n", attr->key, attr->val); } CXML_LOOP_FOREACH_END(); ``` ## 怎么快速在C语言或者C++操作XML? ## **fastxml** 自定了一系列的宏,来方便操作XML文档,具体的示例可以在main.c中看到