什么是YAML?语法、数据类型、用途和陷阱

什么是YAML?语法、数据类型、用途和陷阱

无爬虫抓取API以JSON或CSV返回结构化网页数据,当需要人工编辑的配置边界时,受控管道可以将其转换为YAML。

简言之

  • YAML是一种面向人类的数据序列化语言。 它使用缩进和有限的标点符号表示映射、序列和标量值。
  • YAML在配置文件中很常见。 注释、可读的键、块字符串和紧凑的列表使其在源控制中方便进行设置审查。
  • 空格有助于保持结构。 空格建立嵌套,而制表符处理和不一致的缩进可能会导致错误或意外的数据。
  • 解析器行为必须受到控制。 YAML版本、模式、标签、重复键和隐式类型可以改变文本如何转换为应用程序值。
  • YAML并不适合每条数据路径。 JSON通常对API更清晰,而类型化的二进制或列式格式对大型分析数据集更好。

YAML是什么意思?

YAML意味着'YAML不是标记语言'。它是一种基于Unicode的数据序列化语言,旨在与常见编程结构清晰映射。YAML文档由三种主要节点类型构成:用于键值关联的映射、用于有序集合的序列,以及用于单独值的标量。

YAML 1.2.2规范 描述了表示模型、序列化树、展示流、语法、标签和模式。YAML的展示层提供了几种编写等效数据的方式,这有助于人类作者,但给实现者比JSON更少的语法选择。

YAML是数据,根据定义不是指令语言。应用程序经常使用它来配置部署、构建系统、自动化作业、静态网站元数据和本地开发工具。应用程序决定哪些键是有效的以及这些键的作用。

基本YAML语法

YAML配置可以结合映射、序列、数字、布尔值和嵌套值:

service:
  name: catalog-worker
  enabled: true
  workers: 4
  regions:
    - us-east
    - eu-west
  output:
    format: json
    include_metadata: true

冒号将映射键与其值分开。破折号以块样式引入序列项。缩进放置 name, enabled,其余的设置放置在 service。该文档在此样式下无需大括号或逗号。

映射

映射将键与值关联。键通常是简单字符串,尽管语言模型允许更复杂的键。配置作者应该优先选择简单、唯一的字符串键,因为应用程序库和验证工具可以可预测地处理它们。

重复的映射键是可移植性问题。库可能会拒绝它们,保留一个值,或暴露受选项控制的行为。生产配置加载器应拒绝重复,以便审查员和运行的应用程序看到相同的有效设置。

序列

序列是有序的。块样式每个项使用一个破折号,而流样式使用方括号:

regions: [us-east, eu-west]

checks:
  - name: schema
    required: true
  - name: links
    required: true

每个项可以是标量、映射或另一个序列。只有在应用程序合同赋予其含义时,才应使用顺序。

标量和引用

标量包括字符串、数字、布尔值、空值、某些模式下的时间戳,以及带有显式标签的值。普通标量省略引号,但标点符号和某些单词可能在不同的YAML版本或解析器模式下以意想不到的方式解释。当文本形式必须保持准确(包括版本号、带前导零的标识符,以及类似布尔值或空值的字符串)时,请引用值。

单引号字符串大部分字符按字面意思处理。双引号字符串支持转义序列。块标量使用 | 来保持换行符或 > 将行折叠为空格,附加指示符控制缩进和尾部换行符。

注释、锚、别名和标签

哈希字符以外的引号标量开始注释。注释使YAML对配置变得有吸引力,因为维护者可以解释设置存在的原因。注释是展示的一部分,而不是核心数据模型的一部分,因此许多解析器在加载和写入文档时会舍弃它们。

锚标记节点,别名在其他地方引用该节点。这可以减少重复的配置:

defaults: &defaults
  timeout_seconds: 30
  output: json

jobs:
  catalog:
    <<: *defaults
    region: us-east

此处显示的合并键被广泛使用,但合并行为并不是每个YAML处理路径的简单通用特性。确认所选库和应用程序支持的内容。过多的锚图也使得配置审查更困难,因为有效值不再在一个地方可见。

标签标识节点的类型或解释。标准标签覆盖字符串、整数、映射、序列和其他核心值。一些库支持特定于应用程序的标签,构造语言对象。将不受信任的标签加载到对象构造函数中可能是危险的;请使用安全加载器,将构造限制为预期的数据类型。

YAML模式与版本差异

YAML模式决定标量文本如何解析为标签。版本和模式差异解释了在配置仓库中发现的许多令人惊讶的示例。一个处理模式将某个词解释为布尔值,而在另一个处理模式下可能仍然是字符串。数字语法和时间戳处理也可能有所不同。

YAML 1.2将其JSON模式对齐,以便JSON文档在预期的兼容性模型中是有效的YAML。但这并不意味着每个YAML文件都是有效的JSON:注释、未引用的键、块集合、锚、别名和标签是YAML特性,而不属于JSON语法。

YAML媒体类型规范 注册 application/yaml+yaml 结构语法后缀。仅凭文件扩展名并不能表明解析器架构或应用程序合同。项目应指定解析器库,记录所支持的YAML版本或子集,并根据应用程序架构验证加载的数据。

YAML与JSON

维度YAMLJSON
主要优势人为编写的配置和可读的结构化文档可预测的机器交换和Web APIs
结构缩进、块样式或流样式大括号、方括号、逗号和带引号的属性名
注释支持不是标准JSON的一部分
引用锚和别名没有原生引用语法
解析表面广泛的语法与架构、标签和多种表现样式更小的语法和更少的表现选择
常见文件使用设置、清单、构建和部署配置API有效载荷、事件、应用程序状态、配置
流记录支持多文档流,但应用程序约定各异需要如数组或NDJSON这样的框架

常见YAML用例

应用程序配置

可读的嵌套设置、注释和列表在开发人员检查版本控制中的更改时效果良好。

基础设施清单

声明性系统使用YAML来描述所需资源、政策、关系和部署参数。

自动化管道

构建和交付工具通常使用YAML列出阶段、作业、依赖关系、环境和条件。

文档前言

静态网站和出版工具在人工撰写内容旁边放置小的YAML映射,以声明标题、标签和布局选项。

YAML安全性和可靠性

不可信的YAML应被视为不可信的结构化输入。使用安全加载模式,仅构建普通数据值,而不是特定于语言的对象或应用程序类。一般风险属于更广泛的类别,描述为 CWE-502: 反序列化不可信数据.

限制输入大小、嵌套深度、别名和汇总展开。小文档可以多次引用锚定值,导致加载器创建一个更大的内存结构。库提供不同的控制,因此测试应在具有代表性的限制下测试已部署的解析器。

在解析后验证加载的数据。当配置错误可能危险时,拒绝未知的顶级键。检查必需字段、允许的枚举值、数字范围、路径限制和设置之间的关系。在验证错误时,不要记录机密或完整配置。

常见YAML错误

  • 使用制表符进行缩进。 优先使用空格,并通过编辑器设置和格式化器强制统一的缩进宽度。
  • 留下模糊的标量未引用。 引用标识符和类似于布尔值、null、数字或时间戳的文本。
  • 允许重复的键。 配置加载器或代码检查工具以拒绝它们。
  • 假设评论能够保留在往返过程中。 许多基于对象的加载器丢弃评论和原始格式。
  • 过度使用锚和合并。 重用可以减少重复,但隐藏的有效值使审查和覆盖变得困难。
  • 跳过模式验证。 一个格式良好的文档仍然可能包含拼写错误的键或不安全的值。

如何正确使用YAML

  1. 定义一个小的支持子集。 决定项目是否允许锚、合并键、自定义标签、多文档流和流式样式。
  2. 固定解析器和行为。 记录库、支持的YAML版本、重复键政策和安全加载模式。
  3. 添加代码检查和模式检查。 在部署之前运行它们,以便缩进错误和未知的键能够尽早失败。
  4. 将秘密保存在未提交的YAML外部。 根据应用的文档机制引用环境提供的值或秘密管理器的值。
  5. 审核有效配置。 当存在继承或合并时,提供一个命令,以呈现最终设置而不暴露秘密值。
  6. 当边界发生变化时使用另一种格式。 对于公共API,优先使用JSON,对于大型数据集,优先使用类型化分析格式。

结论

YAML是一种灵活的序列化语言,其可读的块样式使其在配置中尤为有用。它的便利性伴随更大的解释表面:缩进、模式、标签、锚、别名、重复键和解析器选项都可以影响加载的值。一个可靠的YAML工作流缩小了支持的特性集,使用安全加载,验证结果数据,并将人性化的配置与高容量的机器交换区分开。

准备构建结构化的配置工作流了吗?

使用Scrapeless Scraping API收集结构化网络数据,然后只转换您的配置合同允许的验证值。

今天注册并获得 5美元的免费信用无需信用卡.

领取您的5美元信用 →

常见问题

YAML是编程语言吗?

不,YAML是一种数据序列化语言。应用程序可以将YAML键解释为指令,但该行为属于应用程序,而不是YAML本身。

YAML是JSON的超集吗?

YAML 1.2被设计为JSON语法适应其兼容性模型,但真实的解析器支持和边缘情况取决于版本和实现。特定于YAML的语法不是有效的JSON。

为什么缩进在YAML中重要?

缩进定义了块样式YAML中的父子结构。更改空格可以将值移动到另一个映射或序列中,或使文档无效。

YAML可以包含注释吗?

是的,YAML支持以井号开头的注释,位于引号外的标量。许多解析器在加载和写入往返过程中丢弃注释。

从不可信源解析YAML安全吗?

不受信的YAML需要安全加载器、资源限制、禁用特定于应用的对象构造和模式验证。绝不要在不受信的输入上使用通用对象反序列化模式。

参考