结构

2022.06.17

本文按照YAML官方文档1.2.2版本翻译总结而成

https://yaml.org/spec/1.2.2/#chapter-6-structural-productions

6.1. Indentation Spaces

In YAML block styles, structure is determined by indentation. In general, indentation is defined as a zero or more space characters at the start of a line.

To maintain portability, tab characters must not be used in indentation, since different systems treat tabs differently. Note that most modern editors may be configured so that pressing the tab key results in the insertion of an appropriate number of spaces.

The amount of indentation is a presentation detail and must not be used to convey content information.

A block style construct is terminated when encountering a line which is less indented than the construct. The productions use the notation “s-indent-less-than(n)” and “s-indent-less-or-equal(n)” to express this.

Each node must be indented further than its parent node. All sibling nodes must use the exact same indentation level. However the content of each sibling node may be further indented independently.

Example 6.1 Indentation Spaces

··# Leading comment line spaces are ···# neither content nor indentation. ···· Not indented: ·By one space: | ····By four ······spaces ·Flow style: [ # Leading spaces ···By two, # in flow style ··Also by two, # are neither ··→Still by two # content nor ····] # indentation.{ "Not indented": { "By one space": "By four\n spaces\n", "Flow style": [ "By two", "Also by two", "Still by two" ] } }
  

Legend:

The “-”, “?” and “:” characters used to denote block collection entries are perceived by people to be part of the indentation. This is handled on a case-by-case basis by the relevant productions.

Example 6.2 Indentation Indicators

?·a :·-→b ··-··-→c ·····-·d{ "a": [ "b", [ "c", "d" ] ] }
  

Legend:

6.2. Separation Spaces

Outside indentation and scalar content, YAML uses white space characters for separation between tokens within a line. Note that such white space may safely include tab characters.

Separation spaces are a presentation detail and must not be used to convey content information.

Example 6.3 Separation Spaces

-·foo:→·bar - -·baz -→baz[ { "foo": "bar" }, [ "baz", "baz" ] ]
  

Legend:

6.3. Line Prefixes

Inside scalar content, each line begins with a non-content line prefix. This prefix always includes the indentation. For flow scalar styles it additionally includes all leading white space, which may contain tab characters.

Line prefixes are a presentation detail and must not be used to convey content information.

Example 6.4 Line Prefixes

plain: text ··lines quoted: "text ··→lines" block: | ··text ···→lines{ "plain": "text lines", "quoted": "text lines", "block": "text\n \tlines\n" }
  

Legend:

6.4. Empty Lines

An empty line line consists of the non-content prefix followed by a line break.

The semantics of empty lines depend on the scalar style they appear in. This is handled on a case-by-case basis by the relevant productions.

Example 6.5 Empty Lines

Folding: "Empty line ···→ as a line feed" Chomping: | Clipped empty lines ·{ "Folding": "Empty line\nas a line feed", "Chomping": "Clipped empty lines\n" }
  

Legend:

6.5. Line Folding

Line folding allows long lines to be broken for readability, while retaining the semantics of the original long line. If a line break is followed by an empty line, it is trimmed; the first line break is discarded and the rest are retained as content.

Otherwise (the following line is not empty), the line break is converted to a single space (x20).

A folded non-empty line may end with either of the above line breaks.

Example 6.6 Line Folding

>- trimmed↓ ··↓ ·↓ ↓ as↓ space"trimmed\n\n\nas space"
  

Legend:

The above rules are common to both the folded block style and the scalar flow styles. Folding does distinguish between these cases in the following way:

Example 6.7 Block Folding

> ··foo·↓ ·↓ ··→·bar↓ ↓ ··baz↓"foo \n\n\t bar\n\nbaz\n"
  

Legend:

Example 6.8 Flow Folding

"↓ ··foo·↓ ·↓ ··→·bar↓ ↓ ··baz↓ "" foo\nbar\nbaz "
  

Legend:

6.6. Comments

An explicit comment is marked by a “#” indicator. Comments are a presentation detail and must not be used to convey content information.

Comments must be separated from other tokens by white space characters.

Note: To ensure JSON compatibility, YAML processors must allow for the omission of the final comment line break of the input stream. However, as this confuses many tools, YAML processors should terminate the stream with an explicit line break on output.

Example 6.9 Separated Comment

key:····# Comment↓ value*eof*{ "key": "value" }
  

Legend:

Outside scalar content, comments may appear on a line of their own, independent of the indentation level. Note that outside scalar content, a line containing only white space characters is taken to be a comment line.

Example 6.10 Comment Lines

··# Comment↓ ···↓ ↓# This stream contains no # documents, only comments.
  

Legend:

In most cases, when a line may end with a comment, YAML allows it to be followed by additional comment lines. The only exception is a comment ending a block scalar header.

Example 6.11 Multi-Line Comments

key:····# Comment↓ ········# lines↓ value↓ ↓{ "key": "value" }
  

Legend:

6.7. Separation Lines

Implicit keys are restricted to a single line. In all other cases, YAML allows tokens to be separated by multi-line (possibly empty) comments.

Note that structures following multi-line comment separation must be properly indented, even though there is no such restriction on the separation comment lines themselves.

Example 6.12 Separation Spaces

{·first:·Sammy,·last:·Sosa·}:↓ # Statistics: ··hr:··# Home runs ·····65 ··avg:·# Average ···0.278{ { "first": "Sammy", "last": "Sosa" }: { "hr": 65, "avg": 0.278 } }
  

Legend:

6.8. Directives

Directives are instructions to the YAML processor. This specification defines two directives, “YAML” and “TAG”, and reserves all other directives for future use. There is no way to define private directives. This is intentional.

Directives are a presentation detail and must not be used to convey content information.

Each directive is specified on a separate non-indented line starting with the “%” indicator, followed by the directive name and a list of parameters. The semantics of these parameters depends on the specific directive. A YAML processor should ignore unknown directives with an appropriate warning.

Example 6.13 Reserved Directives

%FOO bar baz # Should be ignored # with a warning. --- "foo""foo"
  

Legend:

6.8.1. “YAML” Directives

The “YAML” directive specifies the version of YAML the document conforms to. This specification defines version “1.2”, including recommendations for YAML 1.1 processing.

A version 1.2 YAML processor must accept documents with an explicit “%YAML 1.2” directive, as well as documents lacking a “YAML” directive. Such documents are assumed to conform to the 1.2 version specification. Documents with a “YAML” directive specifying a higher minor version (e.g. “%YAML 1.3”) should be processed with an appropriate warning. Documents with a “YAML” directive specifying a higher major version (e.g. “%YAML 2.0”) should be rejected with an appropriate error message.

A version 1.2 YAML processor must also accept documents with an explicit “%YAML 1.1” directive. Note that version 1.2 is mostly a superset of version 1.1, defined for the purpose of ensuring JSON compatibility. Hence a version 1.2 processor should process version 1.1 documents as if they were version 1.2, giving a warning on points of incompatibility (handling of non-ASCII line breaks, as described above).

Example 6.14 “YAML” directive

%YAML 1.3 # Attempt parsing # with a warning --- "foo""foo"
  

Legend:

It is an error to specify more than one “YAML” directive for the same document, even if both occurrences give the same version number.

Example 6.15 Invalid Repeated YAML directive

%YAML 1.2 %YAML 1.1 fooERROR: The YAML directive must only be given at most once per document.
  

6.8.2. “TAG” Directives

The “TAG” directive establishes a tag shorthand notation for specifying node tags. Each “TAG” directive associates a handle with a prefix. This allows for compact and readable tag notation.

Example 6.16 “TAG” directive

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

Legend:

It is an error to specify more than one “TAG” directive for the same handle in the same document, even if both occurrences give the same prefix.

Example 6.17 Invalid Repeated TAG directive

%TAG ! !foo %TAG ! !foo barERROR: The TAG directive must only be given at most once per handle in the same document.
  

6.8.2.1. Tag Handles

The tag handle exactly matches the prefix of the affected tag shorthand. There are three tag handle variants:

Example 6.18 Primary Tag Handle

# Private !foo "bar" ... # Global %TAG ! tag:example.com,2000:app/ --- !foo "bar"!<!foo> "bar" --- !<tag:example.com,2000:app/foo> "bar"
  

Legend:

Example 6.19 Secondary Tag Handle

%TAG !! tag:example.com,2000:app/ --- !!int 1 - 3 # Interval, not integer!<tag:example.com,2000:app/int> "1 - 3"
  

Legend:

Example 6.20 Tag Handles

%TAG !e! tag:example.com,2000:app/ --- !e!foo "bar"!<tag:example.com,2000:app/foo> "bar"
  

Legend:

6.8.2.2. Tag Prefixes

There are two tag prefix variants:

Example 6.21 Local Tag Prefix

%TAG !m! !my- --- # Bulb here !m!light fluorescent ... %TAG !m! !my- --- # Color here !m!light green!<!my-light> "fluorescent" --- !<!my-light> "green"
  

Legend:

Example 6.22 Global Tag Prefix

%TAG !e! tag:example.com,2000:app/ --- - !e!foo "bar"- !<tag:example.com,2000:app/foo> "bar"
  

Legend:

6.9. Node Properties

Each node may have two optional properties, anchor and tag, in addition to its content. Node properties may be specified in any order before the node’s content. Either or both may be omitted.

Example 6.23 Node Properties

!!str &a1 "foo": !!str bar &a2 baz : *a1{ &B1 "foo": "bar", "baz": *B1 }
  

Legend:

6.9.1. Node Tags

The tag property identifies the type of the native data structure presented by the node. A tag is denoted by the “!” indicator.

Example 6.24 Verbatim Tags

!<tag:yaml.org,2002:str> foo : !<!bar> baz{ "foo": !<!bar> "baz" }
  

Legend:

Example 6.25 Invalid Verbatim Tags

- !<!> foo - !<$:?> barERROR: - Verbatim tags aren't resolved, so ! is invalid. - The $:? tag is neither a global URI tag nor a local tag starting with '!'.
  

Example 6.26 Tag Shorthands

%TAG !e! tag:example.com,2000:app/ --- - !local foo - !!str bar - !e!tag%21 baz[ !<!local> "foo", !<tag:yaml.org,2002:str> "bar", !<tag:example.com,2000:app/tag!> "baz" ]
  

Legend:

Example 6.27 Invalid Tag Shorthands

%TAG !e! tag:example,2000:app/ --- - !e! foo - !h!bar bazERROR: - The !e! handle has no suffix. - The !h! handle wasn't declared.
  

Example 6.28 Non-Specific Tags

# Assuming conventional resolution: - "12" - 12 - ! 12[ "12", 12, "12" ]
  

Legend:

6.9.2. Node Anchors

An anchor is denoted by the “&” indicator. It marks a node for future reference. An alias node can then be used to indicate additional inclusions of the anchored node. An anchored node need not be referenced by any alias nodes; in particular, it is valid for all nodes to be anchored.

Note that as a serialization detail, the anchor name is preserved in the serialization tree. However, it is not reflected in the representation graph and must not be used to convey content information. In particular, the YAML processor need not preserve the anchor name once the representation is composed.

Anchor names must not contain the “[”, “]”, “{”, “}” and “,” characters. These characters would cause ambiguity with flow collection structures.

Example 6.29 Node Anchors

First occurrence: &anchor Value Second occurrence: *anchor{ "First occurrence": &A "Value", "Second occurrence": *A }
  

Legend: