• 知识点滴 - 什么是YAML文件


    今天在看Linux kernel里的device tree的documentation时,发现里面的文档格式都是YAML的,用来描述devicetree某类结点的格式,所以就了解了一下。

    YAML是一种易理解的数据序列化语言,此文件格式通常用于创建配置文件,它的对象序列化能力使它成为JSON等语言的可行替代品。在过去的几年里,其受欢迎程度稳步上升。

    YAML 具有广泛的编程语言支持,并且很容易映射到本地数据结构。它也很容易被人类阅读,这就是为什么它是配置文件的一个好选择。

    YAML是为人类互动而设计的,是另一种数据序列化语言JSON的严格超集。但由于它是一个严格的超集,它可以做JSON可以做的一切,甚至更多。一个主要的区别是,换行符和缩进在YAML中实际上是有意义的,而JSON则使用方括号和大括号。

    YAML发明于2001年,缩写是"Yet Another Markup Language"。但维护者将其更名为YAML Ain't Markup Language,以更加强调其面向数据的特性。

    YAML文件的基本结构是一个地图。你可以把它叫做字典、哈希或对象,这取决于你的编程语言或心情。

    总的来说,YAML大部分都是键值对,keys and values。

    key: value

    让我们来看一个简单的YAML文件:

    ---

    doe: "a deer, a female deer"

    ray: "a drop of golden sun"

    pi: 3.14159

    xmas: true

    french-hens: 3

    calling-birds:

       - huey

       - dewey

       - louie

       - fred

    xmas-fifth-day:

       calling-birds: four

       french-hens: 3

       golden-rings: 5

       partridges:

         count: 1

         location: "a pear tree"

       turtle-doves: two

    该文件以三个破折号开始。这些破折号表示一个新的YAML文档的开始。YAML 支持多个文档,符合要求的解析器会将每一组破折号识别为一个新文档的开始。

    接下来,我们看到构成一个典型YAML文档的大部分结构:一个键值对。Doe是一个指向字符串值的键:a deer, a female deer.。YAML支持的不仅仅是字符串值。该文件以六个键值对开始。它们有四种不同的数据类型。Doe和ray是字符串。Pi是一个浮点数字。Xmas是一个布尔值。French-hens是一个整数。你可以用单引号或双引号将字符串括起来,也可以不用引号。YAML 将未加引号的数字识别为整数或浮点数。第七项是一个数组。Calling-birds有四个元素,每个元素都由一个开头的破折号表示。我在Calling-birds中用两个空格缩进了这些元素。缩进是YAML表示嵌套的方式。各个文件的空格数可以不同,但不允许使用制表符。我们将在下面看看缩进是如何使用的。最后,我们看到xmas-fifth-day,它里面还有五个元素,每个元素都是缩进的。我们可以把xmas-fifth-day看作一个字典,它包含两个字符串、两个整数和另一个字典。YAML 支持键值的嵌套,以及混合类型。在我们深入研究之前,让我们看看这个文档在JSON中的样子。使用这个方便的JSON到YAML的转换器:

    JSON to YAML converter:https://www.json2yaml.com/

    {

      "doe": "a deer, a female deer",

      "ray": "a drop of golden sun",

      "pi": 3.14159,

      "xmas": true,

      "french-hens": 3,

      "calling-birds": [

         "huey",

         "dewey",

         "louie",

         "fred"

      ],

      "xmas-fifth-day": {

      "calling-birds": "four",

      "french-hens": 3,

      "golden-rings": 5,

      "partridges": {

        "count": 1,

        "location": "a pear tree"

      },

      "turtle-doves": "two"

      }

    }

    JSON和YAML有类似的功能,大多数文件都可以在这两种格式之间转换。

    Outline Indentation and Whitespace 大纲缩进和空格

    空格是YAML格式的一部分。除非另有说明,换行符表示一个字段的结束。你用缩进的方式构造YAML文档。缩进程度可以是一个或多个空格。该规范禁止使用制表符,因为不同工具对它们的处理方式不同。比如上面的例子,缩进就是两个空格。

    比如下面格式:

    foo: bar

         pleh: help

         stuff:

           foo: bar

           bar: foo

    实际的值是:

    foo : bar

    pleh : help

    stuff : {'foo': 'bar', 'bar': 'foo'}

    Comments

    注释以#符号开始。它们可以出现在一个值之后,也可独占一行。

    # This is a full line comment

    foo: bar # this is a comment, too

    注释是为了人阅读方便,而YAML处理器会忽略它们。

    YAML Datatypes

    YAML的键值对中的值是标量的。它们的作用类似于Perl、Javascript和Python等语言中的标量类型。通常情况下,将字符串用引号括起来,数字不加引号,解析器就能区分出来了。但这仅仅是冰山一角。YAML 能够做的事情还有很多。

    Scalar Types 标量类型

    你可以使用各种标量类型作为值:数字、布尔和字符串(无论是否有引号)。比如:

    version: 2

    键中的单词可以用下划线、破折号或空格分隔。比如:

    pinctrl-use-default:

      type: boolean

    键值对和字典 Key-Value Pairs and Dictionaries

    键值是YAML的基本构建模块。YAML 文档中的每个条目都是至少一个字典的成员。键总是一个字符串。值是一个标量,因此它可以是任何数据类型。所以,正如我们已经看到的,值可以是一个字符串,一个数字,或另一个字典。

    数值类型 Numeric types

    YAML 可以识别数字类型。我们在上面看到了浮点和整数。YAML 支持其他几种数字类型。一个整数可以是十进制、十六进制或八进制。

    ---

    foo: 12345

    bar: 0x12d4

    plop: 023332

    正如你所期望的,Ox表示一个值是十六进制的,而前导零表示一个八进制的值。YAML同时支持固定和指数浮点数。

    ---

    foo: 1230.15

    bar:  12.3015e+05

    最后,我们可以表示非数字(NAN / not-a-number)或无穷大 / infinity。

    ---

    foo: .inf

    bar: -.Inf

    plop: .NAN

    Foo是无穷大,bar是负的无穷大,plop是NAN。

    Strings 字符串

    YAML 字符串是 Unicode 的。在大多数情况下,你不需要用引号。

    ---

    foo: this is a normal string

    但如果我们想处理转义序列,我们需要使用双引号。

    ---

    foo: "this is not a normal string\n"

    bar: this is not a normal string\n

    YAML将第一个值处理为以回车键和换行键( carriage return and linefeed)结束。由于第二个值没有引号,YAML将其视为两个字符。

    YAML中单引号不会解释转义字符串。字符串的值可以跨越多于一行。通过fold(大于)字符,你可以在一个块中指定一个字符串。

    bar: >

      this is not a normal string it

      spans more than

      one line

      see?

    但这样赋值后,会忽略换行,实际上相当于:

    bar : this is not a normal string it spans more than one line see?

    Block(pipe管道)字符有类似的功能,但YAML完全按原样解释该字段。

    bar: |

      this is not a normal string it

      spans more than

      one line

      see?

    这样的换行符也包含在值中:

    bar : this is not a normal string it

    spans more than

    one line

    see?

    如果一个键的值是一个多行字符串,你可以使用'|'字符的'literal block'风格。这在定义shell命令时特别有用:

    command: |

        if [ "${CIRCLE_BRANCH}" == "master" ];

          then ansible-playbook site.yml -i production;

        fi

    注意,多行字符串的前导缩进将被删除。

    Nulls 空值

    你可以用tilde或无引号的null字符串来输入nulls。

    ---

    foo: ~

    bar: null

    这样使用工具打印出这个键的值,可能如下:

    foo : None

    bar : None

    这个使用Python打印出的值显示,在Python里,null的显示是None。

    Booleans 布尔值

    YAML用关键字True、On和Yes表示表示真。假则用False、Off或No表示。

    ---

    foo: True

    bar: False

    light: On

    TV: Off

    Arrays 数组

    你可以在单行上指定数组或列表:

    ---

    items: [ 1, 2, 3, 4, 5 ]

    names: [ "one", "two", "three", "four" ]

    或者放到多行上:

    ---

    items:

      - 1

      - 2

      - 3

      - 4

      - 5

    names:

      - "one"

      - "two"

      - "three"

      - "four"

    多行格式对包含复杂对象而不是标量的列表很有用。

    ---

    items:

      - things:

          thing1: huey

          things2: dewey

          thing3: louie

      - other things:

          key: value

    一个数组可以包含任何有效的YAML值。列表中的值不一定是相同的类型。

    Dictionaries 字典 (或者叫Collection Types 集合类型

    我们在上面介绍了字典,但它们还有更多的意义。像数组一样,你可以把字典的内容一行显示。我们在上面看到了这种格式。这是python打印字典的方式。

    ---

    foo: { thing1: huey, thing2: louie, thing3: dewey }

    同样的内容,也可以改成像前面一样的跨行显示,你要做的就是使用缩进来创建字典或集合:

    ---

    foo: 

      thing1: huey

      thing2: louie

      thing3: dewey

    可以多级嵌套。

    Advanced Options 高级选项

    Chomp Modifiers

    多行的字符串可能以空格(比如换行符)结束,根据你希望文档被处理的方式,你可能希望保留或不保留。YAML 有 strip chomp 和 preserve chomp 操作符。

    要保存最后一个字符,请在fold或block运算符上添加一个加号。

    bar: >+

      this is not a normal string it

      spans more than

      one line

      see?

    这样bar的值就不再是一行,而是多行。

    使用| 操作符时,默认时保留换行符,如果要去掉这个结尾换行符,请使用strip(剥离) 操作符,即减号。

    bar: |-

      this is not a normal string it

      spans more than

      one line

      see?

    Multiple documents 多文档

    一个文档以三个破折号(dash)开始,以三个句号(periods)结束。一些YAML处理器需要文档的开始运算符。结束符通常是可选的。例如,Java的Jackson不会处理没有开始的YAML文件,但Python的PyYAML可以。当一个文件包含多个文档时,你通常会使用文档结束操作符。

    总结

    YAML 是一种强大的语言,可用于配置文件、应用程序之间的消息和保存应用程序的状态。我们介绍了它最常用的功能,包括如何使用内置的数据类型和结构复杂的文件。一些平台支持YAML的高级功能,包括自定义数据类型。

    注意,YAML不允许使用制表符tab,所以如果你使用这些字符缩进,请让你的文本编辑器将其转换为空格。

    参考:

    What is YAML? A beginner's guide | CircleCI

    YAML Tutorial: Everything You Need to Get Started in Minutes | Cloudbees Blog

    Learn yaml in Y Minutes

    YAML Ain’t Markup Language (YAML™) revision 1.2.2

    YAMLlint - The YAML Validator

  • 相关阅读:
    Go基础语法:函数+
    Python 编程基础 | 第三章-数据类型 | 3.5、列表
    docker学习笔记
    自动化运维管理工具 Ansible
    youtubu视频下载和yt-dlp 使用教程
    彻底掌握Protobuf编码原理与实战
    JavaScript事件循环
    git 把master分支代码合并到自己分支(常用git 命令)
    【Python】让Anaconda不再下载慢下载失败,Anaconda的下载源更换为国内源(保姆级图文)
    2024 ,Android 15 预览版来了
  • 原文地址:https://blog.csdn.net/guoqx/article/details/126718648