12 Star 57 Fork 24

Josin / fastxml

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
BSD-3-Clause-Clear

fastxml 纯C语言编写的XML解析库

什么是fastxml?

fastxml是一款支持XML解析的多根节点的解析引擎,支持特性如下:

  • 支持多根 XML,一个 XML 文档支持多个 ROOT 标记,如下包含informationlist

    <?xml version="1.0" encoding="UTF-8"?>
    <information>
      <name>Josin</name>
      <age>26</age>
      <address>Changsha</address>
    </information>
    
    <list>
    	<name>Linux</name>
    	<version>v5.0.1</version>
    	<tool>Git</tool>
    </list>
  • 支持单一元素直接闭合语法

    <?xml version="1.0" encoding="UTF-8"?>
    <information>
      <name>Josin</name>
      <age>26</age>
      <address>Changsha</address>
      <other_info/><!--直接闭合-->
    </information>
  • 支持XML文档声明,声明必须位于第一行,以及众多属性,标准的XML声明如下:

    <?xml version="1.0" encoding="UTF-8" author="Josin"?>
  • 支持标记的属性特性,如下面的 information 标记包含的 idpid 属性:

    <?xml version="1.0" encoding="UTF-8"?>
    <information id="11" pid="99">
        <name>Josin</name>
        <age>26</age>
        <address>Changsha</address>
    </information>
  • 支持注释注意:注释不可以嵌套

    <?xml version="1.0" encoding="UTF-8"?>
    <information id="11" pid="99">
        <!--<name>Josin</name>-->
        <age>2<!--6--></age>
        <address>Changsha</address>
    </information>
  • 支持 CDATA标记 防止浏览器转义

    <?xml version="1.0" encoding="UTF-8" author="Josin"?>
    <!--This is the comments-->
    <information>
        <name><![CDATA[Josin]]></name>
        <!--<age>26</age>-->
        <address>Hunan</address>
    </information>
  • 暂不支持特性:DTD规则以及校验

编译 & 运行

fastxml 使用纯C99语法编写,可以使用在支持标准C99的操作系统上,fastxml使用 cmake编译管理系统,推荐版本 3.13以及以上

git clone https://gitee.com/josinli/fastxml.git
cd fastxml
mkdir build
cd build
cmake .. && make 
./fastxml 

性能测试

性能测试基准平台:MacBook ProLinux 平台性能更高, 解析大约22KB 的 XML 文档 1100 次耗时 1 秒

APIs 列表

  • 从字符串解析 XML,返回 NULL 表示XML文件格式错误
CXML *new_cxml_from_string2(char *str, unsigned long long);
  • 从CXML中编码为字符串,返回的字符串需要通过 free 函数释放
char *new_string_from_cxml(CXML *c);
  • 获取解码 XML 的错误信息
char  *new_cxml_get_error();
  • 生成CXML对象
CXML *cxml_new_cxml(char *tag, char *version, char *encoding);	
  • 给CXML对象添加根节点
int cxml_add_root_node(CXML *xml, CXML_NODE *node);
  • 生成CXML节点信息
CXML_NODE *cxml_make_node(char *name, unsigned long nlen, char *text/*可以为NULL*/, unsigned long tlen/*可以为0*/);
  • 给CXML节点添加属性
int cxml_node_add_attr(CXML_NODE *cnode, char *key, unsigned long klen, char *val, unsigned long vlen);
  • 给CXML节点添加节点
int cxml_node_add_node(CXML_NODE *cnode, CXML_NODE *snode);
  • 释放编码后的 CXML 信息
int   trash_cxml(CXML *v);

快捷操作宏

操作节点的宏:

// 用来定义一个 CXML_n 的结构来存储解码后的XML信息
CXML_FIELD_DEF(n)
// 中间使用 *aname 来定义一个节点名称, 前面的 * 不能省略
CXML_FIELD_DEF_END(n);
// 用来声明函数,用来在其他的文件引入声明
CXML_FIELD_FUNC_DEF(n);
// 上面的声明的实现文件
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();

操作节点属性的宏:

// 用来定义一个 CXML_n 的结构来存储解码后的XML信息
CXML_ATTR_DEF(n)
// 中间使用 *aname 来定义一个节点名称, 前面的 * 不能省略
CXML_ATTR_DEF_END(n);
// 用来声明函数,用来在其他的文件引入声明
CXML_ATTR_FUNC_DEF(n);
// 上面的声明的实现文件
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

如果需要遍历某一个节点下的所有子节点,可以使用如下宏:

// 第一个参数为父节点的 data 属性
// 第二个参数为自定义的 CXML_NODE 元素的指针
CXML_LOOP_FREACH_DATA(data, cnode) {
	  // 这里访问 cnode 元素内容即可
    // printf("%s:%s\n", cnode->key->s, cnode->sval->s);
}CXML_LOOP_FOREACH_END()

遍历某一个子节点的所有的属性信息,使用如下宏:

// 第一个参数为需要遍历属性节点的 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中看到

The Clear BSD License Copyright (c) 2019, Josin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

简介

纯C编写的XML解析引擎 展开 收起
C 等 3 种语言
BSD-3-Clause-Clear
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C
1
https://gitee.com/josinli/fastxml.git
git@gitee.com:josinli/fastxml.git
josinli
fastxml
fastxml
master

搜索帮助