前言
YAML(Yet Another Markup Language)是一种人类可读的数据序列化格式,常用于(如K8S及Ansible)配置文件和数据交换。在C语言中,我们可以使用libyaml来解析和处理YAML格式的数据, libcyaml 是基于libyaml 封装的基于schema的YAML解析和序列化工具, 基于ISC协议开源,用户能够方便集成到业务代码。本文将介绍如何使用libcayml实现解析YAML到结构体。
前置准备
1. 安装依赖包
libcayml 基于libyaml作为底层的YAML读写库,因此需要安装libyaml及其开发库,否则在编译时将出现错误。
$ yum install -y libyaml libyaml-devel |
2. 下载代码
git clone github.com/tlsa/libcyaml.git lib cd lib git clone v1.4.1 -b v1.4.1 |
项目集成
1. 打开调试开关
在项目中,通常需要打开调试便于后期问题定位,因此修改Makefile打开编译调试开关
diff --git a/Makefile b/Makefile # Default variant depends on whether it's a development build. ifneq ($(filter coverage,$(MAKECMDGOALS)),) |
2. 代码开发
参考代码仓库中examples/planner/main.c 进行代码开发:
定义结构体
struct task { const char **depends; const char **people; |
定义结构体对应的schema:
static const cyaml_schema_field_t task_fields_schema[] = { static const cyaml_schema_value_t task_schema = { |
如果结构体作为另外一个结构体的成员, 可以参考plan的相关定义:
struct plan { … struct task *tasks; uint64_t tasks_count; }; |
Schema定义:
static const cyaml_schema_field_t plan_fields_schema[] = { … CYAML_FIELD_SEQUENCE( "tasks", CYAML_FLAG_POINTER, struct plan, tasks, &task_schema, 0, CYAML_UNLIMITED), … }; |
YAML 配置
static const cyaml_config_t config = { .log_fn = cyaml_log, .mem_fn = cyaml_mem, .log_level = CYAML_LOG_INFO, }; |
这里使用默认的日志及内存分配函数,如有需要可实现自定义的方法。
解析yaml文件到结构体
err = cyaml_load_file(argv[ARG_PATH_IN], &config, &plan_schema, (void **) &plan, NULL); |
序列化结构体并写到文件:
err = cyaml_save_file(argv[ARG_PATH_OUT], &config, &plan_schema, plan, 0); |
最后,别记得释放内存:
cyaml_free(&config, &plan_schema, plan, 0); |
编译libcayml到源码
CFLAGS += -I lib/include LIBS = -lyaml -Llib -lcyaml OBJS = main.o all: libs $(TARGET) libs: $(TARGET): $(OBJS) |
执行make命令即能完成代码编译。
总结
YAML是一种方便人类阅读和编写的数据序列化格式,在C语言中可以使用libyaml库来解析和处理YAML格式的数据。本文介绍了如何使用基于libyaml封装的开源libcyaml库,以及如何使用libcyaml库来加载、解析和处理YAML文件。