Documents
A YAML file or Stream can contain multiple Documents.
YAML Libraries typically have functions like load and load_all to read only one or all documents.
Document Start
A Document can explicitly be started with ---. In the specification this is called the "Directives end marker".
Since directives are not used very often, and a lot of YAML users don't know they exist, this can be confusing. I will call it "Document Start".
For the first document, the Document Start is optional, but it is also a way to mark something as YAML explicitly:
--- # with optional document start marker invoice number: 314159 name: Santa Claus address: North Pole
If a file contains multiple documents, they must be separated with the document start marker:
--- # The first one is still optional invoice number: 314159 name: Santa Claus address: North Pole --- invoice number: 314160 name: Santa Claus address: North Pole --- invoice number: 314161 name: Santa Claus address: North Pole
The Document Start is usually on its own line. Mappings or Sequences must start on the next line.
If a document's top level node is a scalar, then it can also start on the same line:
--- | # Top Level Block Scalar line 1 line 2 line 3 --- top level plain scalar
In case of top level scalars, it is recommended to always use the document start marker, and always indent the content. Some libraries don't accept a top level scalar which is not indented.
Document End
There is also the Document End Marker ....
It is also optional, but useful or recommended in some cases.
Open Ended Block Scalars
Sometimes Block Scalars can have trailing newlines:
block: |+ line 1 line 2 line 3 more: content
In the previous example, the value for block will have three trailing linebreaks.
In the following example, it also has three linebreaks:
block: |+ line 1 line 2 line 3
The problem here is, if this is the last item in the file, it might easily happen that someone editing the file accidentally adds another line at the end or saves the file without the last line ending.
In these cases, it's recommended to explicitly end the document:
block: |+ line 1 line 2 line 3 ...
Streaming Context
When YAML is used in a Stream, for example over network, it might be important to tell the receiver that the document has ended:
--- invoice number: 314159 name: Santa Claus address: North Pole ... # time passes... --- invoice number: 314160 name: Santa Claus address: North Pole ... # time passes... --- invoice number: 314161 name: Santa Claus address: North Pole ...
Theoretically it's also possible to only use the Document End Marker to separate Documents:
invoice number: 314159 name: Santa Claus address: North Pole ... invoice number: 314160 name: Santa Claus address: North Pole ... invoice number: 314161 name: Santa Claus address: North Pole ...
However, that's not supported by all libraries. To be safe, always use the Document start marker when using multiple documents.
Directives
YAML has two Directives:
- YAML Version Directive
- YAML Tag Directive
YAML Version Directive
The Version directive is used to tell the YAML processor which version of YAML the document is written in.
%YAML 1.2 --- a: mapping
If you use a directive, the Document Start Marker must always follow. That's why in the YAML Specification, it is called "Directives End Marker".
In YAML 1.2, a directive is only applied to the following document, not to the whole file or stream.
So if you have multiple documents, you need both the Document Start and End Markers:
%YAML 1.2 --- invoice number: 314159 name: Santa Claus address: North Pole ... %YAML 1.2 --- invoice number: 314160 name: Santa Claus address: North Pole ... %YAML 1.2 --- invoice number: 314161 name: Santa Claus address: North Pole
YAML Tag Directive
Tag Directives are rarely used.
They provide a way to create shorthand tags for custom processing.
An example is the Unity3d application (which is using YAML 1.1).
%YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!header SerializedFile: # ...
It maps tags like !u!header to tag:unity3d.com,2011:header.
There is only one tag directive which always used by default, so you don't have to specify this in a YAML file:
%TAG !! tag:yaml.org,2002: --- # ...
This allows to use the standard YAML tags like !!int or !!bool in their short form.
But the standard YAML tags are rarely needed. Read more about Tags and Schema in the Schema Chapter.