【YAML】YAML语言|YAML配置文件|YAML库用法|相比json的区别优势YAML库编译与使用

时间:2022-10-20 07:11:44


目录

​YAML简介​

​官方定义​

​我的理解​

​基本的语法结构​

​1. 当数据类型是字面量​

​2.当数据类型是对象、键值对的集合​

​3.当数据类型是数组、一组按次序排列的值​

​YAML库编译与使用​

​库的下载与编译安装​

​使用例子​

​YAML和 json的区别(有何优势)​

​区别​

​ 在线转换工具​


YAML简介

官方定义

    YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据​​序列化​​的格式。

  • YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。
  • 它非常适合用来做以数据为中心的配置文件。

我的理解

YAML(YAML Ain’t Markup Language),YAML 是一种简洁的非标记语言

1、YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读。

2、YAML是一种可读的文本的数据结构,它的设计目标是使人们容易读,程序容易处理。它类似XML,但是比XML简单。广泛用于配置文件,日志文件,跨语言数据共享,对象持久化,复杂的数据结构。

3、YAML 的配置文件后缀为 .yml,如:libai.yml 。

就是一种标记语言,适合用来编写以数据为中心的配置文件。

(参考:​​YAML和JSON对比-https://bbs.huaweicloud.com/blogs/298709)​

YAML配置文件

用YAML语言编写的配置文件。

YAML库

提供读取YAML语言编写的配置文件的配置项的API的库。

基本的语法结构

  • key: value;key:与value之间有空格
  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格(但是在idea中可以放心使用tab来进行缩进,目前还没有出现什么问题)
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释
  • 字符串无需加引号,如果要加, ""与 ''表示字符串内容会被转义或不转义。
  • 其中单引号''字符串内容不会被转义,举个例子' \n '会输出\n这个字符串
  • 双引号 "" 字符串内容会被转义,举个例子"\n "会把\n进行转义输出换行回车

1. 当数据类型是字面量

  • 字面量:单个的、不可再分的值。date、boolean、string、number、null

语法为:(​​k:​​​与​​v​​之间必须加空格。)

#`k:`与`v`之间必须加空格
k: v

2.当数据类型是对象、键值对的集合

  • 对象、键值对的集合:map、hash、set、object

语法为:(行内写法时​​k:​​​与​​v​​​之间可以不加空格,一般写法时​​k:​​​与​​v​​之间必须加空格)

#行内写法:(行内写法时`k:`与`v`之间可以不加空格)  
k: {k1:v1,k2:v2,k3:v3}
#或一般写法:(一般写法时`k:`与`v`之间必须加空格)
k: 
  k1: v1
  k2: v2
  k3: v3

3.当数据类型是数组、一组按次序排列的值

  • 数组、一组按次序排列的值:array、list、queue

语法为:(​​k:​​​与​​v​​​之间,​​-​​​与​​v​​之间都必须加空格)

#`k:`与`v`之间,`-`与`v`之间都必须加空格
行内写法:  k: [v1,v2,v3]
#或者
k:
 - v1
 - v2
 - v3

实战示例:

【YAML】YAML语言|YAML配置文件|YAML库用法|相比json的区别优势YAML库编译与使用

输出结果:

【YAML】YAML语言|YAML配置文件|YAML库用法|相比json的区别优势YAML库编译与使用

YAML库编译与使用

库的下载与编译安装

yaml官网

​http://yaml.org/​

yaml下载官网

​http://pyyaml.org/wiki/LibYAML​

下载网址

​http://pyyaml.org/download/libyaml​

在我写这篇文章的时候这个网站已经无法访问了,不清楚是什么原因,我最后得到的版本是yaml-0.1.7.tar.gz

编译源码

1、解压源码包

rt@ubuntu:~/yaml/yaml-0.1.7$ tar xvf yaml-0.1.7.tar.gz 

rt@ubuntu:~/yaml/yaml-0.1.7$ cd yaml-0.1.7/
2、生成makefile文件

rt@ubuntu:~/yaml/yaml-0.1.7$ ./configure --prefix=/home/rt/opt/yaml

其中--prefix=为安装路径,如果需要安装到自己系统中就不要添加后面的参数,直接./configure即可,后面的make install需要sudo权限。

3、编译、安装

rt@ubuntu:~/yaml/yaml-0.1.7$ make

rt@ubuntu:~/yaml/yaml-0.1.7$ make install

此时在安装路径下就有生成的文件了。
 

使用例子

应用程序调用YAML库的编程接口读取YAML文件

yaml文件:Invoice.yaml

%TAG !yaml! tag:yaml.org,2002:
---
!e!foo "bar"

--- !<tag:clarkevans.com,2002:invoice>
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
458 Walkman Dr.
Suite #292
city : Royal Oak
state : MI
postal : 48046
ship-to: *id001
product:
- sku : BL394D
quantity : 4
description : Basketball
price : 450.00
- sku : BL4438H
quantity : 1
description : Super Hoop
price : 2392.00
tax : 251.42
total: 4443.52
comments:
Late afternoon is best.
Backup contact is Nancy
Billsmer @ 338-4338.

读取的代码run-scanner.c

#include <yaml.h>

#include <stdlib.h>
#include <stdio.h>

#ifdef NDEBUG
#undef NDEBUG
#endif
#include <assert.h>

int
main(int argc, char *argv[])
{
int number;

if (argc < 2) {
printf("Usage: %s file1.yaml ...\n", argv[0]);
return 0;
}

for (number = 1; number < argc; number ++)
{
FILE *file;
yaml_parser_t parser;
yaml_token_t token;
int done = 0;
int count = 0;
int error = 0;

fflush(stdout);

file = fopen(argv[number], "rb");
assert(file);

assert(yaml_parser_initialize(&parser));

yaml_parser_set_input_file(&parser, file);

while (!done)
{
if (!yaml_parser_scan(&parser, &token)) {
error = 1;
break;
}

switch(token.type)
{
case YAML_STREAM_START_TOKEN:
printf("YAML_STREAM_START_TOKEN: encoding=%d\n", token.data.stream_start.encoding);
break;
case YAML_STREAM_END_TOKEN:
printf("YAML_STREAM_END_TOKEN\n");
break;
case YAML_VERSION_DIRECTIVE_TOKEN:
printf("YAML_VERSION_DIRECTIVE_TOKEN: major=%d, minor=%d\n", token.data.version_directive.major, token.data.version_directive.minor);
break;
case YAML_TAG_DIRECTIVE_TOKEN:
printf("YAML_TAG_DIRECTIVE_TOKEN: handle=%s, prefix=%s\n", token.data.tag_directive.handle, token.data.tag_directive.prefix);
break;
case YAML_DOCUMENT_START_TOKEN:
printf("YAML_DOCUMENT_START_TOKEN\n");
break;
case YAML_DOCUMENT_END_TOKEN:
printf("YAML_DOCUMENT_END_TOKEN\n");
break;
case YAML_BLOCK_SEQUENCE_START_TOKEN:
printf("YAML_BLOCK_SEQUENCE_START_TOKEN\n");
break;
case YAML_BLOCK_MAPPING_START_TOKEN:
printf("YAML_BLOCK_MAPPING_START_TOKEN\n");
break;
case YAML_BLOCK_END_TOKEN:
printf("YAML_BLOCK_END_TOKEN\n");
break;
case YAML_FLOW_SEQUENCE_START_TOKEN:
printf("YAML_FLOW_SEQUENCE_START_TOKEN\n");
break;
case YAML_FLOW_SEQUENCE_END_TOKEN:
printf("YAML_FLOW_SEQUENCE_END_TOKEN\n");
break;
case YAML_FLOW_MAPPING_START_TOKEN:
printf("YAML_FLOW_MAPPING_START_TOKEN\n");
break;
case YAML_FLOW_MAPPING_END_TOKEN:
printf("YAML_FLOW_MAPPING_END_TOKEN\n");
break;
case YAML_BLOCK_ENTRY_TOKEN:
printf("YAML_BLOCK_ENTRY_TOKEN\n");
break;
case YAML_FLOW_ENTRY_TOKEN:
printf("YAML_FLOW_ENTRY_TOKEN\n");
break;
case YAML_KEY_TOKEN:
printf("YAML_KEY_TOKEN\n");
break;
case YAML_VALUE_TOKEN:
printf("YAML_VALUE_TOKEN\n");
break;
case YAML_ALIAS_TOKEN:
printf("YAML_ALIAS_TOKEN: value=%s\n", token.data.alias.value);
break;
case YAML_ANCHOR_TOKEN:
printf("YAML_ANCHOR_TOKEN: value=%s\n", token.data.anchor.value);
break;
case YAML_TAG_TOKEN:
printf("YAML_TAG_TOKEN: handle=%s, suffix=%s\n", token.data.tag.handle, token.data.tag.suffix);
break;
case YAML_SCALAR_TOKEN:
{
printf("YAML_SCALAR_TOKEN: value=%s, length=%lu, style=%d\n", token.data.scalar.value, token.data.scalar.length, token.data.scalar.style);
}
break;
}
done = (token.type == YAML_STREAM_END_TOKEN);

yaml_token_delete(&token);

count ++;
}

yaml_parser_delete(&parser);

assert(!fclose(file));

printf("[%d] Scanning '%s': ", number, argv[number]);
printf("%s (%d tokens)\n", (error ? "FAILURE" : "SUCCESS"), count);
}

return 0;
}

编译和指定链接yaml库,生成可执行文件:scanfile 

执行gcc run-scanner.c -o scanfile -lyaml -I/home/rt/opt/yaml/include -L/home/rt/opt/yaml/lib

执行scanfile 

rt@ubuntu:~/yaml$ ./scanfile Invoice.yaml 
YAML_STREAM_START_TOKEN: encoding=1
YAML_TAG_DIRECTIVE_TOKEN: handle=!yaml!, prefix=tag:yaml.org,2002:
YAML_DOCUMENT_START_TOKEN
YAML_TAG_TOKEN: handle=!e!, suffix=foo
YAML_SCALAR_TOKEN: value=bar, length=3, style=3
YAML_DOCUMENT_START_TOKEN
YAML_TAG_TOKEN: handle=, suffix=tag:clarkevans.com,2002:invoice
YAML_BLOCK_MAPPING_START_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=invoice, length=7, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=34843, length=5, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=date, length=4, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=2001-01-23, length=10, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=bill-to, length=7, style=1
YAML_VALUE_TOKEN
YAML_ANCHOR_TOKEN: value=id001
YAML_BLOCK_MAPPING_START_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=given, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Chris, length=5, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=family, length=6, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Dumars, length=6, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=address, length=7, style=1
YAML_VALUE_TOKEN
YAML_BLOCK_MAPPING_START_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=lines, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=458 Walkman Dr.
Suite #292
, length=27, style=4
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=city, length=4, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Royal Oak, length=9, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=state, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=MI, length=2, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=postal, length=6, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=48046, length=5, style=1
YAML_BLOCK_END_TOKEN
YAML_BLOCK_END_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=ship-to, length=7, style=1
YAML_VALUE_TOKEN
YAML_ALIAS_TOKEN: value=id001
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=product, length=7, style=1
YAML_VALUE_TOKEN
YAML_BLOCK_SEQUENCE_START_TOKEN
YAML_BLOCK_ENTRY_TOKEN
YAML_BLOCK_MAPPING_START_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=sku, length=3, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=BL394D, length=6, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=quantity, length=8, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=4, length=1, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=description, length=11, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Basketball, length=10, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=price, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=450.00, length=6, style=1
YAML_BLOCK_END_TOKEN
YAML_BLOCK_ENTRY_TOKEN
YAML_BLOCK_MAPPING_START_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=sku, length=3, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=BL4438H, length=7, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=quantity, length=8, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=1, length=1, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=description, length=11, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Super Hoop, length=10, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=price, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=2392.00, length=7, style=1
YAML_BLOCK_END_TOKEN
YAML_BLOCK_END_TOKEN
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=tax, length=3, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=251.42, length=6, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=total, length=5, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=4443.52, length=7, style=1
YAML_KEY_TOKEN
YAML_SCALAR_TOKEN: value=comments, length=8, style=1
YAML_VALUE_TOKEN
YAML_SCALAR_TOKEN: value=Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338., length=68, style=1
YAML_BLOCK_END_TOKEN
YAML_STREAM_END_TOKEN
[1] Scanning 'Invoice.yaml': SUCCESS (112 tokens)

YAML和 json的区别(有何优势)

(摘自:​​现代配置YAML对比JSON优势分析_https://www.ab62.cn/article/6842.html​​)

区别

将 yaml 看做是 json 的升级,因为 yaml 在格式简化和体验上表现确实不错,这个得承认。

yaml:

my_dictionary:
  - list_value_one
  - list_value_two
  - list_value_three
等同于json:
{"my_dictionary":["list_value_one","list_value_two","list_value_three"]}
 

1)精简了符号。

josn  k和v 都加 ​​""​​ 才行:只能这样

{ "name": "ruims" }

yaml

name: ruims

2)增加了注释支持

用 JSON 写配置是不能有注释的,这就意味着我们的配置不会有备注,配置多了会非常凌乱,这是最不人性化的地方。

现在 yaml 支持了备注,以后配置可以是这样的:


# 应用名称 name: my_app # 应用端口 port: 8080


JSON是什么干什么的?

JSON(JavaScript Object Notation):JavaScript 对象表示法

1、它不是一种语言,它是一种轻量级的文本数据交换格式。

2、它使用Javascript语法来描述数据对象,但它独立于JavaScript。JSON解析器和JSON库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。

3、它本身是一串字符串,只是它是一串有固定格式的字符串。符合这个数据格式要求的字符串,我们称之为JSON。文件后缀名.json,libai.json.

简单来说JSON是一种数据格式,和数组作用一样,用于存储数据。

更多YAML和JSON的区别:​​https://bbs.huaweicloud.com/blogs/298709​

 在线转换工具

在线转换工具:​​在线YAML转JSON工具 - https://tooltt.com/yaml2json/​