YAML Ain’t Markup Language(YAML™)バージョン 1.2

改訂 1.2.2(2021-10-01)

Copyright presently by YAML Language Development Team1
Copyright 2001-2009 by Oren Ben-Kiki, Clark Evans, Ingy döt Net

この文書は、変更されていないことを条件に、自由に複製できます。

この文書のステータス

これは YAML 仕様 v1.2.2 です。 これは YAML 1.2 データ言語 を定義します。 YAML 仕様 v1.2 からの規範的な変更はありません。 この改訂の主な目的は、誤りを修正し、明確さを加えることです。

この改訂はまた、YAML 言語の開発プロセスを、より オープンで、より透明性が高く、人々が貢献しやすいものにすることを目指しています。 入力形式は DocBook ではなく Markdown になり、画像はプロプライエタリな描画ソフトウェアではなく、 プレーンテキストの LaTeX ファイルから作成されるようになりました。 仕様のすべてのソースコンテンツは公開されています2

以前の YAML 仕様3 は 12 年前に公開されました。 その間に、YAML の人気は大きく高まりました。 言語を改善し、ユーザーのニーズと期待に応えられるように成長させる取り組みが継続しています。 この仕様の改訂では YAML に実質的な変更は加えられていませんが、 言語が進化し、現代的であり続けるためのプロセスを開始します。

YAML 仕様は、非常に単純に見えるものとしては過度に複雑だと見なされることがよくあります。 YAML はソフトウェア構成によく使用されますが、常に完全なデータ直列化言語であり、 今後もそうあり続けます。 今後の YAML の計画は、実装者のために開発プロセスを簡素化すると同時に、 言語とエコシステムをより強力で信頼性の高いものにすることに重点を置いています。

この仕様の改訂は情報提供上の変更のみに限定されていますが、 YAML フレームワーク実装者および YAML 言語ユーザーを導くことを目的とした 付随文書があります。 この文書は、この仕様の公開改訂の間にも継続的に進化し、拡張され続けることができます。

参照:

概要

YAML™(“camel” と韻を踏みます)は、人間にとって扱いやすく、言語横断的で、Unicode ベースの データ直列化言語であり、動的プログラミング言語に共通するネイティブデータ型を中心に設計されています。 構成ファイルからインターネットメッセージング、オブジェクト永続化、データ監査、 可視化に至るまで、プログラミング上の幅広いニーズに有用です。 文字に関する Unicode 標準4 と併せて、この仕様は YAML バージョン 1.2 を理解し、YAML 情報を処理するプログラムを作成するために必要な すべての情報を提供します。

目次

第1章 YAML 入門

YAML(“YAML Ain’t Markup Language” の再帰的頭字語)は、人間にとって扱いやすく、 一般的な日常タスクにおいて現代的なプログラミング言語とうまく連携するよう設計された データ直列化言語です。 この仕様は、YAML 言語とそれを支える概念の入門であると同時に、 YAML を処理するための アプリケーションを開発するために必要な情報の 完全な仕様でもあります。

オープンで、相互運用可能で、容易に理解できるツールは、コンピューティングを 大きく進歩させてきました。 YAML は最初から、データを扱う人々にとって有用で親しみやすいものとして設計されました。 これは Unicode の印字可能文字を使用し、その一部は構造情報を提供し、 残りはデータそのものを含みます。 YAML は、構造文字の量を最小化し、データが自然で意味のある形で自らを示せるようにすることで、 独自のすっきりした表現を実現しています。 たとえば、構造にはインデントを使用でき、コロンキー/値ペアを区切り、ダッシュは “箇条書き” のリストを作成するために使用されます。

データ構造には多くの種類がありますが、それらはすべて、 表現上、3 つの基本プリミティブで十分に扱えます。すなわち、 マッピング(ハッシュ/辞書)、 シーケンス(配列/リスト)、および スカラー (文字列/数値)です。 YAML はこれらのプリミティブを活用し、単純な型付けシステムとエイリアス 機構を追加することで、任意の直列化可能なネイティブデータ 構造のための完全な言語を形成します。 ほとんどのプログラミング言語はデータ直列化に YAML を使用できますが、YAML は、 3 つの基本プリミティブを基盤として構築されている言語と連携する場合に特に優れています。 これには JavaScript、Perl、PHP、Python、Ruby などの一般的な動的言語が含まれます。

プログラミングのための言語は何百種類もありますが、データの保存と転送のための言語は ごくわずかしかありません。 YAML の可能性は実質的に無限ですが、これは特に、 構成ファイル、ログファイル、プロセス間メッセージング、言語横断のデータ共有、 オブジェクト永続化、複雑なデータ構造のデバッグといった一般的なユースケースに うまく対応するために作られました。 データを見やすく理解しやすくすることで、プログラミングはより単純な作業になります。

1.1. 目的

YAML の設計目標は、優先度の高い順に次のとおりです。

  1. YAML は人間が容易に読めるべきである。
  2. YAML データはプログラミング言語間で移植可能であるべきである。
  3. YAML は動的言語のネイティブデータ 構造に適合すべきである。
  4. YAML は汎用ツールを支える一貫したモデルを持つべきである。
  5. YAML はワンパス処理をサポートすべきである。
  6. YAML は表現力があり、拡張可能であるべきである。
  7. YAML は実装しやすく、使いやすいべきである。

1.2. YAML の歴史

YAML 1.0 仕様は、yaml-core メーリングリスト5を通じた 3 年間の共同設計作業の後、2004 年初頭に Clark Evans、Oren Ben-Kiki、Ingy döt Net によって公開されました。 このプロジェクトは当初、Clark と Oren による SML-DEV6 メーリングリスト(XML の単純化を目的とするもの)での作業と、 Ingy の Perl 用プレーンテキスト直列化モジュール7に根ざしていました。 この言語は、それ以前に存在した多くの技術や形式から多くの着想を得ています。

最初の YAML フレームワークは 2001 年に Perl で書かれ、Ruby は 2003 年に コア言語ディストリビューションの一部として YAML フレームワークを同梱した最初の 言語でした。

YAML 1.18 仕様は 2005 年に公開されました。 この頃、開発者たちは JSON9 の存在を知りました。 まったくの偶然により、JSON は(構文的にも意味的にも)ほぼ完全な YAML のサブセットでした。

2006 年、Kyrylo Simonov は PyYAML10 と LibYAML11 を作成しました。 さまざまなプログラミング言語における多くの YAML フレームワークは LibYAML の上に構築されており、 また多くの実装者は PyYAML を実装の堅実な参照としてきました。

YAML 1.23 仕様は 2009 年に公開されました。 その主な焦点は、YAML を JSON の厳密なスーパーセットにすることでした。 また、問題のある暗黙的型付けの推奨事項の多くも削除されました。

1.2 仕様の公開以降、YAML の採用は拡大し続け、多くの大規模プロジェクトが 主要なインターフェース言語として YAML を使用しています。 2020 年、新しい YAML 言語設計チームは、YAML 言語と仕様の改善について、 ユーザーとユースケースのニーズおよび期待によりよく応えるために、定期的な会合を開始しました。

2021 年 10 月に公開されたこの YAML 1.2.2 仕様は、 YAML の再活性化された開発の道のりにおける最初の一歩です。 YAML はこれまでになく人気がありますが、その潜在能力を最大限に発揮するためには、 対処すべきことが長いリストとして残っています。 YAML 設計チームは、YAML を可能な限り優れたものにすることに注力しています。

1.3. 用語

この文書におけるキーワード “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、 “SHOULD NOT”、“RECOMMENDED”、“MAY”、“OPTIONAL” は、 RFC 211912 に記述されているように 解釈されます。

この文書の残りの部分は次のように構成されています。 第 2 章では、YAML の主要機能の短い概観を示します。 第 3 章では、YAML 情報モデルと、 このモデルおよび YAML テキスト形式との間で変換するためのプロセスについて説明します。 文書の大部分を占める第 456789 章では、このテキスト形式を形式的に定義します。 最後に、第 10 章では基本的な YAML スキーマを推奨します。

第2章 言語の概要

この節では、YAML の表現力を簡単に垣間見せます。 初めて読む読者がすべての例を完全に理解することは期待されていません。 むしろ、これらの抜粋は仕様の残りの部分への動機付けとして使用されます。

2.1. コレクション

YAML のブロックコレクションは、 スコープにインデントを使用し、各項目を それぞれ独自の行で開始します。 ブロックシーケンスは、各項目をダッシュとスペース(“- ”)で示します。 マッピングは、コロンとスペース(“: ”)を使用して、各キー/値ペアを示します。 コメントは、オクトソープ(“hash”、“sharp”、 “pound” または “number sign” とも呼ばれる “#”)で始まります。

例 2.1 スカラーのシーケンス(野球選手)

- Mark McGwire
- Sammy Sosa
- Ken Griffey

例 2.2 スカラーからスカラーへのマッピング(選手統計)

hr:  65    # Home runs
avg: 0.278 # Batting average
rbi: 147   # Runs Batted In

例 2.3 スカラーからシーケンスへのマッピング(各リーグの球団)

american:
- Boston Red Sox
- Detroit Tigers
- New York Yankees
national:
- New York Mets
- Chicago Cubs
- Atlanta Braves

例 2.4 マッピングのシーケンス(選手の統計)

-
  name: Mark McGwire
  hr:   65
  avg:  0.278
-
  name: Sammy Sosa
  hr:   63
  avg:  0.288

YAML にはフロースタイルもあり、 スコープを示すためにインデントではなく、 明示的な指示子を使用します。 フローシーケンスは、 括弧の中にカンマ区切りのリストとして書かれます。 同様に、フローマッピング括弧を使用します。

例 2.5 シーケンスのシーケンス

- [name        , hr, avg  ]
- [Mark McGwire, 65, 0.278]
- [Sammy Sosa  , 63, 0.288]

例 2.6 マッピングのマッピング

Mark McGwire: {hr: 65, avg: 0.278}
Sammy Sosa: {
    hr: 63,
    avg: 0.288,
 }

2.2. 構造

YAML は 3 つのダッシュ(“---”)を使用して、 ディレクティブ文書 内容から分離します。 これは、ディレクティブが存在しない場合に文書の開始を示す 役割も果たします。 3 つのドット(“...”)は、 通信チャネルで使用するために、新しい文書を開始せずに文書の終端を示します。

例 2.7 ストリーム内の 2 つの文書(それぞれ先頭コメント付き)

# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey

# Team ranking
---
- Chicago Cubs
- St Louis Cardinals

例 2.8 試合からのプレイバイプレイフィード

---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...

繰り返されるノード(オブジェクト)は、最初にアンカーによって 識別されます(アンパサンド - “&” で示されます)。その後は、 エイリアス化されます(アスタリスク - “*” で参照されます)。

例 2.9 2 つのコメントを持つ単一文書

---
hr: # 1998 hr ranking
- Mark McGwire
- Sammy Sosa
# 1998 rbi ranking
rbi:
- Sammy Sosa
- Ken Griffey

例 2.10 “Sammy Sosa” のノードが この文書に 2 回現れる

---
hr:
- Mark McGwire
# Following node labeled SS
- &SS Sammy Sosa
rbi:
- *SS # Subsequent occurrence
- Ken Griffey

疑問符とスペース(“? ”)は、 複雑なマッピングキーを示します。 ブロックコレクション内では、キー/値 ペアは、ダッシュコロン、または疑問符の直後から開始できます。

例 2.11 シーケンス間のマッピング

? - Detroit Tigers
  - Chicago cubs
: - 2001-07-23

? [ New York Yankees,
    Atlanta Braves ]
: [ 2001-07-02, 2001-08-12,
    2001-08-14 ]

例 2.12 コンパクトな入れ子マッピング

---
# Products purchased
- item    : Super Hoop
  quantity: 1
- item    : Basketball
  quantity: 4
- item    : Big Shoes
  quantity: 1

2.3. スカラー

スカラー内容は、ブロック記法で書くことができます。 その場合、リテラルスタイル (“|” で示される)を使用すると、すべての改行が意味を持ちます。 あるいは、折り畳みスタイル(“>” で示される)で書くこともできます。 この場合、各改行は、行または より深くインデントされた行の終端でない限り、 スペース折り畳まれます。

例 2.13 リテラルでは改行が保持される

# ASCII Art
--- |
  \//||\/||
  // ||  ||__

例 2.14 折り畳みスカラーでは改行がスペースになる

--- >
  Mark McGwire's
  year was crippled
  by a knee injury.

例 2.15 折り畳まれた改行は、“より深くインデントされた” 行と空行では保持される

--- >
 Sammy Sosa completed another
 fine season with great stats.

   63 Home Runs
   0.288 Batting Average

 What a year!

例 2.16 インデントがスコープを決定する

name: Mark McGwire
accomplishment: >
  Mark set a major league
  home run record in 1998.
stats: |
  65 Home Runs
  0.278 Batting Average

YAML のフロースカラーには、プレーン スタイル(これまでの例の大半)と 2 つの引用スタイルが含まれます。 二重引用スタイルエスケープシーケンスを提供します。 単一引用スタイルは、エスケープが不要な場合に有用です。 すべてのフロースカラーは複数行にまたがることができ、 改行は常に折り畳まれます。

例 2.17 引用スカラー

unicode: "Sosa did fine.\u263A"
control: "\b1998\t1999\t2000\n"
hex esc: "\x0d\x0a is \r\n"

single: '"Howdy!" he cried.'
quoted: ' # Not a ''comment''.'
tie-fighter: '|\-*-/|'

例 2.18 複数行フロースカラー

plain:
  This unquoted scalar
  spans many lines.

quoted: "So does this
  quoted scalar.\n"

2.4. タグ

YAML では、タグのないノードには、アプリケーションに応じた型が与えられます。 この仕様の例では、一般にフェイルセーフスキーマseqmapstr 型を使用します。 いくつかの例では、JSON スキーマintfloatnull 型も使用します。

例 2.19 整数

canonical: 12345
decimal: +12345
octal: 0o14
hexadecimal: 0xC

例 2.20 浮動小数点

canonical: 1.23015e+3
exponential: 12.3015e+02
fixed: 1230.15
negative infinity: -.inf
not a number: .nan

例 2.21 その他

null:
booleans: [ true, false ]
string: '012345'

例 2.22 タイムスタンプ

canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

明示的な型付けは、感嘆符(“!”)記号を使用するタグで示されます。 グローバルタグは URI であり、 ハンドルを使用するタグ短縮形記法で 指定できます。 アプリケーション固有のローカルタグも 使用できます。

例 2.23 さまざまな明示的タグ

---
not-date: !!str 2002-04-28

picture: !!binary |
 R0lGODlhDAAMAIQAAP//9/X
 17unp5WZmZgAAAOfn515eXv
 Pz7Y6OjuDg4J+fn5OTk6enp
 56enmleECcgggoBADs=

application specific tag: !something |
 The semantics of the tag
 above may be different for
 different documents.

例 2.24 グローバルタグ

%TAG ! tag:clarkevans.com,2002:
--- !shape
  # Use the ! handle for presenting
  # tag:clarkevans.com,2002:circle
- !circle
  center: &ORIGIN {x: 73, y: 129}
  radius: 7
- !line
  start: *ORIGIN
  finish: { x: 89, y: 102 }
- !label
  start: *ORIGIN
  color: 0xFFEEBB
  text: Pretty vector drawing.

例 2.25 順序なし集合

# Sets are represented as a
# Mapping where each key is
# associated with a null value
--- !!set
? Mark McGwire
? Sammy Sosa
? Ken Griffey

例 2.26 順序付きマッピング

# Ordered maps are represented as
# A sequence of mappings, with
# each mapping having one key
--- !!omap
- Mark McGwire: 65
- Sammy Sosa: 63
- Ken Griffey: 58

2.5. 完全な長さの例

以下に、YAML の完全な長さの例を 2 つ示します。 1 つ目は請求書の例で、2 つ目はログファイルの例です。

例 2.27 請求書

--- !<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.

例 2.28 ログファイル

---
Time: 2001-11-23 15:01:42 -5
User: ed
Warning:
  This is an error message
  for the log file
---
Time: 2001-11-23 15:02:31 -5
User: ed
Warning:
  A slightly different error
  message.
---
Date: 2001-11-23 15:03:17 -5
User: ed
Fatal:
  Unknown variable "bar"
Stack:
- file: TopClass.py
  line: 23
  code: |
    x = MoreObject("345\n")
- file: MoreClass.py
  line: 58
  code: |-
    foo = bar

第3章 プロセスとモデル

YAML は、テキスト形式であると同時に、この形式で任意のネイティブデータ 構造提示するための方法でもあります。 したがって、この仕様は 2 つの概念を定義します。YAML 表現と呼ばれる データオブジェクトのクラスと、YAML 表現を、YAML ストリームと呼ばれる一連の文字として提示するための構文です。

YAML プロセッサーは、これらの相補的な視点の間で情報を変換するためのツールです。 YAML プロセッサーは、アプリケーションと呼ばれる別のモジュールのために 作業を行うものと想定されます。 この章では、YAML プロセッサーがアプリケーションに提供する、またはアプリケーションから取得する必要がある 情報構造について説明します。

YAML 情報は、機械処理と人間による利用という 2 つの方法で使用されます。 これら 2 つの観点を調和させる課題は、表現直列化提示という 3 つの明確な変換段階で扱うのが最適です。 表現は、プログラミング環境間の移植性を実現するために、 YAML がネイティブデータ構造をどのように見るかを扱います。 直列化は、YAML 表現を、 逐次アクセス制約を持つ形式、すなわち直列形式へ変換することを扱います。 提示は、YAML 直列化を、人間にとって扱いやすい形で一連の文字として 整形することを扱います。

3.1. プロセス

ネイティブデータ構造と文字ストリームの間の変換は、 いくつかの論理的に区別される段階で行われます。それぞれには明確に定義された入力と出力の データモデルがあり、次の図に示されています。

図 3.1. 処理の概要

処理の概要

YAML プロセッサーは、直列化または表現の段階を 公開する必要はありません。 これは、ネイティブデータ構造と文字 ストリームの間を直接変換しても構いません(上の図における ダンプロード)。 ただし、そのような直接変換は、ネイティブデータ 構造表現で利用可能な情報のみから 構築されるように行うべきです。 特に、マッピングキーの順序コメントタグハンドルは、 構築中に参照されるべきではありません。

3.1.1. ダンプ

ネイティブデータ構造を文字ストリームダンプすることは、 次の 3 段階を使用して行われます。

ネイティブデータ構造の表現

YAML は、3 つのノード種別を使用して、任意のネイティブデータ構造表現します。 シーケンス - 順序付けられた項目の列、マッピング - 一意キーからへの順序なし関連付け、そして スカラー - Unicode 文字列として提示可能な不透明な構造を持つ任意のデータです。

これらのプリミティブを組み合わせることで、有向グラフ構造が生成されます。 これらのプリミティブが選ばれたのは、強力でありながらなじみ深いからです。 シーケンスは Perl の配列や Python のリストに対応し、 マッピングは Perl のハッシュテーブルや Python の辞書に対応します。 スカラーは、文字列、整数、日付、その他の原子的データ型を表します。

各 YAML ノードは、その種別内容に加えて、 データ型を指定するタグを必要とします。 型指定子は、グローバル URI であるか、単一の アプリケーション内のスコープにローカルです。 たとえば、整数は YAML では、スカラーグローバル タグtag:yaml.org,2002:int” によって表現されます。 同様に、特定の組織に固有の請求書オブジェクトは、マッピングローカル タグ!invoice” を組み合わせて 表現できます。 この単純なモデルは、プログラミング言語に依存せず、任意のデータ構造を表現できます。

表現グラフの直列化

イベントコールバック API のような逐次アクセス媒体では、YAML 表現は、順序付けられたツリーへ直列化されなければなりません。 YAML 表現では、マッピングキーが順序を持たず、ノードが 複数回参照される(複数の入力 “矢印” を持つ)可能性があるため、 直列化プロセスは、マッピングキー順序付けを課し、 あるノードへの 2 回目以降の参照を、 エイリアスと呼ばれるプレースホルダーに置き換えることが求められます。 YAML は、これらの直列化詳細をどのように選択するかを指定しません。 人間にとって扱いやすいキー順序アンカー名を、 必要に応じてアプリケーションの助けを借りて考え出すのは、 YAML プロセッサーの責任です。 このプロセスの結果である YAML 直列化ツリーは、 YAML データのワンパス処理のために一連のイベント呼び出しを生成するために走査できます。

直列化ツリーの提示

最終的な出力プロセスは、YAML 直列化を、人間にとって扱いやすい形で 文字ストリームとして提示することです。 人間による可読性を最大化するために、YAML は単純なデータ保存の最小限の機能的要件を 大きく超える豊富なスタイル上の選択肢を提供します。 したがって YAML プロセッサーは、 ストリームを作成するとき、ノードスタイルの選択、 スカラー内容の整形方法インデント量、使用するタグ ハンドル未指定のままにする ノードタグ、提供するディレクティブの集合、 さらには追加するコメントなど、さまざまな提示 詳細を導入する必要があります。 これらの一部はアプリケーションの助けを借りて行うことができますが、 一般にはこのプロセスはユーザーの好みによって導かれるべきです。

3.1.2. ロード

文字ストリームからネイティブデータ構造ロードすることは、次の 3 段階を使用して行われます。

提示ストリームの解析

解析提示の逆プロセスです。これは文字のストリームを受け取り、 直列化ツリーを生成します。 解析は、提示プロセスで導入された 詳細をすべて破棄し、 直列化ツリーのみを報告します。 解析は、整形式でない入力によって失敗する可能性があります。

表現グラフの構成

構成は、直列化ツリーを受け取り、 表現グラフを生成します。 構成は、直列化プロセスで導入された 詳細をすべて破棄し、 表現グラフのみを生成します。 構成は、以下で詳述するいくつかの理由のいずれかによって失敗する可能性があります。

ネイティブデータ構造の構築

最終的な入力プロセスは、YAML 表現から ネイティブデータ構造構築することです。 構築は、表現で利用可能な情報のみに基づかなければならず、 直列化提示 詳細であるコメントディレクティブマッピングキー順序ノードスタイルスカラー内容の形式インデントレベルなどの追加情報に基づいてはなりません。 構築は、必要なネイティブデータ 型利用できないことによって失敗する可能性があります。

3.2. 情報モデル

この節では、上記のプロセスの結果に関する形式的な詳細を規定します。 プログラミング言語および実装間でのデータ移植性を最大化するために、 YAML の利用者は、直列化または 提示のプロパティと、YAML 表現の一部であるプロパティとの区別に注意すべきです。 したがって、YAML 表現を逐次アクセス媒体へ平坦化するために マッピング キー順序を課すことは必要ですが、この直列化 詳細を、アプリケーションレベルの情報を伝えるために 使用してはなりません。 同様に、インデント技法やノード スタイルの選択は人間の可読性のために必要ですが、これらの提示詳細は YAML 直列化にも YAML 表現にも含まれません。 直列化および 提示に必要なプロパティを慎重に分離することで、 アプリケーション情報の YAML 表現は、 さまざまなプログラミング環境間で一貫性があり、移植可能になります。

次の図は、3 つの情報モデルを要約しています。 塗りつぶされた矢印は合成を、白抜きの矢印は継承を、“1” と “*” は “1 つ” と “多数” の 関係を示します。 単一の “+” は 直列化詳細を、二重の “++” は 提示詳細を示します。

図 3.2. 情報モデル

情報モデル

3.2.1. 表現グラフ

YAML によるネイティブデータ 構造表現は、根を持ち、連結された、 タグ付きノードの有向グラフです。 “有向グラフ” とは、ノードと有向辺(“矢印”)の集合を意味し、 各辺は 1 つのノードを別のノードに接続します (形式的な有向グラフの定義を参照13)。 すべてのノードは、そのような辺を通じてルートノードから到達可能でなければなりません。 YAML グラフにはサイクルが含まれる場合があり、1 つのノードが複数の 入力辺を持つ場合があることに注意してください。

他のノードによって定義されるノードコレクションであり、他のノードから独立した ノードスカラーです。 YAML は 2 種類のコレクションノードをサポートします。 シーケンスマッピングです。 マッピングノードは、キーが順序を持たず、 一意でなければならないため、やや扱いが難しいものです。

図 3.3. 表現モデル

表現モデル

3.2.1.1. ノード

YAML ノードは、単一のネイティブデータ構造表現します。 そのようなノードは、スカラー、シーケンス、マッピングのいずれか 1 つの種別内容を持ちます。 さらに、各ノードには、その内容が取り得る値の集合を制限するタグがあります。

スカラー

スカラーノードの内容は、0 個以上の Unicode 文字列として 提示できる不透明なデータです。

シーケンス

シーケンスノードの内容は、0 個以上のノードの順序付けられた列です。 特に、シーケンスは同じノードを複数回含むことができます。 自分自身を含むことさえできます。

マッピング

マッピングノードの内容は、キー/値ノード ペアの順序なし集合であり、各キーが一意であるという制約があります。 YAML はノードに対してそれ以上の制限を課しません。 特に、キーは任意のノードでよく、同じノードを複数のキー/値ペアの値として使用でき、 マッピングが自分自身をキーまたは値として含むことさえできます。

3.2.1.2. タグ

YAML は、ネイティブデータ構造の型情報を、 タグと呼ばれる単純な識別子で表現します。 グローバルタグは URI であるため、すべてのアプリケーションにわたってグローバルに一意です。 “tag:” URI スキーム14 は、すべてのグローバル YAML タグに推奨されます。 これに対して、ローカルタグは単一のアプリケーションに固有です。 ローカルタグは “!” で始まり、 URI ではなく、グローバルに一意であることは期待されません。 YAML はタグ表記を簡潔にするために “TAG” ディレクティブを提供し、ローカルタグからグローバルタグへの容易な移行も提供します。 これを保証するために、ローカルタグは URI 文字集合に制限され、URI 文字の エスケープを使用します。

YAML は、同じ部分文字列で始まる異なるタグ間に特別な関係を義務付けません。 URI フラグメント(“#” を含む)で終わるタグも例外ではなく、 同じベース URI を共有していてもフラグメント部分が異なるタグは、 互いに独立した異なるタグと見なされます。 慣例として、フラグメントはタグの異なる “バリアント” を識別するために使用され、 “/” は入れ子のタグ “名前空間” 階層を定義するために使用されます。 ただし、これは単なる慣例であり、各タグは独自の規則を採用できます。 たとえば、Perl タグは名前空間階層を表すために “::” を使用し、 Java タグは “.” を使用する、などです。

YAML タグは、各ノードにメタ情報を関連付けるために使用されます。 特に、各タグは期待されるノード種別スカラーシーケンスまたはマッピング)を指定しなければなりません。 スカラータグは、等価性検査をサポートするために、整形された内容正準形式へ変換する機構も提供しなければなりません。 さらに、タグは、検証のために許可される内容値の集合、 タグ解決の機構、またはそのタグのすべてのノードに 適用されるその他のデータなど、追加情報を提供できます。

3.2.1.3. ノード比較

YAML マッピングではキーの一意性が必要なため、 表現には、ノードの等価性を検査するための 機構が含まれていなければなりません。 YAML ではスカラー内容を整形するさまざまな方法が許されるため、 これは自明ではありません。 たとえば、整数 11 は “0o13”(8 進)または “0xB” (16 進)として書くことができます。 同じマッピング内のキーとして両方の表記が使用された場合、整数形式を認識する YAML プロセッサーだけが、重複するキーをエラーとして正しく報告できます。

正準形式

YAML はスカラー等価性の必要性をサポートするため、すべての スカラー タグが、任意の 整形された内容から正準 形式を生成する機構を指定することを要求します。 この形式は、同じ内容提示する Unicode 文字列であり、 等価性検査に使用できます。

等価性

2 つのノード等しいためには、同じタグと 同じ内容を持たなければなりません。 各タグは正確に 1 つの種別に適用されるため、 これは、等しくなるには 2 つの ノードが同じ種別を持たなければならないことを意味します。

2 つのスカラーは、それらのタグと 正準形式が文字ごとに等しい場合にのみ等しくなります。 コレクションの等価性は再帰的に定義されます。

2 つのシーケンスは、同じタグと長さを持ち、 一方のシーケンス内の各ノードが、 他方のシーケンス内の対応するノードと等しい場合にのみ 等しくなります。

2 つのマッピングは、同じタグと等しいキー集合を持ち、 この集合内の各キーが、両方の マッピングにおいて等しいに関連付けられている場合にのみ 等しくなります。

異なる URI スキームは、URI の等価性を検査するための異なる規則を定義することがあります。 YAML プロセッサーがそれらすべてを認識していると 合理的に期待することはできないため、一貫性を保証するためにタグの 単純な文字ごとの比較に頼らなければなりません。 これは、“tag:” URI スキームによって定義される比較方法でもあります。 したがって、YAML ストリーム内のタグは、 そのような比較が正しい結果を生むように、正準的な方法で 提示されなければなりません。

ノードが(エイリアスを介して)自分自身を子孫として持つ場合、そのノードの等価性の判定は 実装定義です。

YAML プロセッサーは、等しいスカラーを同一であるかのように扱っても構いません。

一意性

マッピングキーは、どの 2 つのキーも互いに等しくない場合、 一意です。 明らかに、同一のノードは常に等しいと見なされます。

3.2.2. 直列化ツリー

YAML 表現を直列 API を使用して表すには、 マッピングキー順序を課し、 以前に遭遇したノードの後続出現を示すために エイリアスノードを使用する必要があります。 このプロセスの結果は直列化ツリーであり、各ノードは順序付けられた子の集合を持ちます。 このツリーは、直列イベントベース API のために走査できます。 直列インターフェースからネイティブデータ構造構築する際には、 アプリケーションデータの保存のために キー順序アンカー 名を使用すべきではありません。

図 3.4. 直列化モデル

直列化モデル

3.2.2.1. マッピングキー順序

表現モデルでは、マッピング キーは順序を持ちません。 マッピング直列化するには、 そのキー順序付けを課す必要があります。 この順序は直列化詳細であり、 表現グラフ構成するとき (したがってアプリケーションデータの保存のために) 使用すべきではありません。 ノードの順序が重要であるすべての場合において、 シーケンスを使用しなければなりません。 たとえば、順序付きマッピングは、各マッピングが 単一のキー/値ペアであるシーケンスとして 表現できます。 YAML はこの場合のために便利なコンパクト記法を提供します。

3.2.2.2. アンカーとエイリアス

表現グラフでは、1 つのノードが 複数のコレクションに現れる場合があります。 そのようなデータを直列化するとき、 そのノードの最初の出現はアンカーによって 識別されます。 それ以降の各出現は、このアンカーを参照するエイリアスノードとして 直列化されます。 それ以外の場合、アンカー名は直列化 詳細であり、 構成が完了すると破棄されます。 直列化されたイベントから表現グラフ構成する場合、エイリアスイベントは、 指定されたアンカーを持つ直列化内の最も最近のイベントを参照します。 したがって、アンカーは直列化内で一意である必要はありません。 さらに、アンカーにはそれを参照するエイリアスノードがなくても構いません。

3.2.3. 提示ストリーム

YAML 提示は、ストリームである Unicode 文字列であり、 スタイルスカラー内容形式コメントディレクティブ、その他の 提示詳細を使用して、YAML 直列化を人間が読める形で 提示します。 YAML は、同じ YAML 提示ストリーム内に、マーカーで区切られた一連の文書として、複数の直列化ツリーを 含めることを許します。

図 3.5. 提示モデル

提示モデル

3.2.3.1. ノードスタイル

ノードは、その種別に応じて何らかのスタイルで提示されます。 ノードスタイルは提示詳細であり、 直列化ツリーにも 表現グラフにも反映されません。 スタイルには 2 つのグループがあります。 ブロックスタイルは構造を示すために インデントを使用します。 これに対して、フロースタイルは明示的な 指示子に依存します。

YAML は豊富なスカラースタイルを提供します。 ブロックスカラースタイルには、リテラルスタイル折り畳みスタイルが含まれます。 フロースカラースタイルには、プレーン スタイルと 2 つの引用スタイル、すなわち 単一引用スタイル二重引用スタイルが含まれます。 これらのスタイルは、表現力と可読性の間でさまざまなトレードオフを提供します。

通常、ブロックシーケンスマッピングは 次の行で始まります。 場合によっては、YAML は、よりコンパクトな記法のために、 入れ子になったブロックコレクションがインラインで始まることも許します。 さらに、YAML は、フローシーケンス内に入れ子になった 単一のキー/値ペアを持つフローマッピングのための コンパクト 記法を提供します。 これにより、自然な “順序付きマッピング” 記法が可能になります。

図 3.6. 種別/スタイルの組み合わせ

種別/スタイルの組み合わせ

3.2.3.2. スカラー形式

YAML は、スカラーをいくつかの形式提示することを許します。 たとえば、整数 “11” は “0xB” と書くこともできます。 タグは、等価性検査で使用するために、 整形された内容を正準形式へ変換する機構を指定しなければなりません。 ノードスタイルと同様に、形式は提示詳細であり、 直列化ツリーおよび 表現グラフには反映されません。

3.2.3.3. コメント

コメント提示 詳細であり、 直列化ツリーまたは 表現グラフに影響を与えてはなりません。 特に、コメントは特定のノードに関連付けられません。 コメントの通常の目的は、ファイルの人間の保守者同士で情報を伝えることです。 典型的な例は構成ファイル内のコメントです。 コメントはスカラーの内部に現れてはなりませんが、そのような スカラーを含むコレクション内に 挿入されても構いません。

3.2.3.4. ディレクティブ

文書には、ディレクティブの集合を関連付けることができます。 ディレクティブには名前と、任意のパラメーター列があります。 ディレクティブは YAML プロセッサーへの命令であり、 他のすべての提示詳細と同様に、 YAML 直列化ツリーまたは 表現グラフには反映されません。 このバージョンの YAML は、“YAML” と “TAG” の 2 つのディレクティブを定義します。 それ以外のすべてのディレクティブは、YAML の将来バージョンのために 予約されています。

3.3. ロード失敗点

YAML ストリームからネイティブ データ構造ロードするプロセスには、 いくつかの潜在的な失敗点があります。 文字ストリーム整形式でない場合があり、エイリアス未識別の場合があり、 未指定タグ解決不能の場合があり、 タグ認識不能の場合があり、 内容無効の場合があり、 マッピングキー一意でない場合があり、ネイティブ型が 利用不能の場合があります。 これらの各失敗は、不完全なロードをもたらします。

部分表現では、各ノードタグ解決する必要はなく、 整形されたスカラー内容正準形式も 利用可能である必要はありません。 この弱い表現は、文書で使用されている型についての知識が不完全な場合に有用です。

これに対して、完全表現は、各ノードタグを指定し、 整形された スカラー内容正準形式を提供し、 等価性検査を可能にします。 ネイティブデータ 構造構築するには、完全表現が必要です。

図 3.7. ロード失敗点

ロード失敗点

3.3.1. 整形式ストリームと識別済み エイリアス

整形式の文字ストリームは、 以降の章で指定される BNF 生成規則に一致しなければなりません。 ロードの成功には、各エイリアスが、以前の ノード識別する アンカーを参照することも必要です。 YAML プロセッサーは、整形式でないストリーム未識別 エイリアスを拒否すべきです。 YAML プロセッサーは、場合によっては入力の一部を無視することで 構文エラーから回復しても構いませんが、そのようなエラーを報告する機構を提供しなければなりません。

3.3.2. 解決済みタグ

通常、ほとんどのタグは文字ストリーム内で明示的に指定されません。 解析中に、明示的なタグを持たない ノードには非固有 タグが与えられます。すなわち、非プレーンスカラーには “!”、その他すべてのノードには “?” です。 完全表現構成するには、 そのような各非固有タグを、グローバルタグまたはローカルタグのいずれかである固有タグ解決する必要があります。

ノードタグの解決は、次の 3 つの パラメーターのみに依存しなければなりません。(1) ノードの非固有タグ、 (2) ルートからノードに至るパス、 (3) ノード内容(したがって種別)です。 ノードが(エイリアスを使用して)複数回出現する場合、タグ解決は、 そのノードの最初の(アンカー付き) 出現へのパスのみに依存しなければなりません。

解決は、コメントインデントノードスタイルなどの 提示 詳細を考慮してはならないことに注意してください。 また、解決は、ルートから解決対象の ノードに至るパス上に直接ある キーノード内容を除き、 他のノード内容を考慮してはなりません。 最後に、解決は、コレクション内の兄弟ノード内容や、 解決対象のキーノードに関連付けられた値ノード内容を 考慮してはなりません。

これらの規則により、ノードストリーム内で 最初に現れた時点で、多くの場合その内容解析される前に、 タグ解決を行うことができます。 また、タグ解決には、比較的少数の、以前に解析されたノードを参照するだけで済みます。 したがって、ほとんどの場合、ワンパスプロセッサーにおける タグ解決は可能であり、実用的でもあります。

YAML プロセッサーは、“!” 非固有タグを持つノードを、その種別に応じて “tag:yaml.org,2002:seq”、 “tag:yaml.org,2002:map” または “tag:yaml.org,2002:str” として 解決すべきです。 このタグ解決規約により、YAML 文字ストリームの作者は、タグ解決プロセスを効果的に “無効化” できます。 “!” 非固有タグプロパティを 明示的に指定することで、そのノードは、 その種別に従って “素の” シーケンスマッピング、または文字列へ解決されます。

アプリケーション固有のタグ解決規則は、 “?” 非固有タグの解決に限定されるべきであり、 最も一般的にはプレーンスカラーの解決に使用されます。 これらは、整数、浮動小数点数、タイムスタンプ、および類似の型の自動解決を提供するために、 正規表現の集合と照合される場合があります。 アプリケーションはまた、マッピングノード内容を 期待されるキーの集合と照合して、点、複素数、および類似の型を 自動的に解決しても構いません。 “順序付きマッピング” のような解決済みシーケンスノード型も可能です。

とはいえ、タグ解決はアプリケーションに固有です。 したがって、YAML プロセッサーは、 アプリケーションがこれらの既定のタグ解決規則を 上書きおよび拡張できる機構を提供すべきです。

文書未解決タグが含まれている場合、YAML プロセッサー完全表現グラフを 構成できません。 そのような場合、YAML プロセッサーは、各 ノードの種別に基づき、非固有タグを許容して、 部分表現構成しても構いません。

3.3.3. 認識済みで妥当なタグ

ノード妥当であるためには、YAML プロセッサーによって認識される タグを持ち、その内容が このタグによって課される制約を満たさなければなりません。 文書が、認識されないタグまたは無効な 内容を持つスカラーノードを含む場合、 部分表現のみを構成できます。 これに対して、YAML プロセッサーは、認識されない、または無効な コレクションについては、常に完全 表現構成できます。 なぜなら、コレクション等価性は、 コレクションのデータ型に関する知識に依存しないからです。 ただし、そのような完全表現は、 ネイティブデータ構造構築するためには使用できません。

3.3.4. 利用可能なタグ

ある処理環境において、特定のタグに対応する利用可能なネイティブ型が 存在する必要はありません。 ノードのタグ利用不能である場合、YAML プロセッサーは、そのノードの ネイティブデータ構造構築できません。 この場合でも、完全表現構成することは可能であり、 アプリケーションはこの 表現を直接使用したい場合があります。

第4章 構文規約

以下の章では、パラメーター化された BNF 生成規則を使用して、YAML 文字ストリームの構文を形式的に定義します。 各 BNF 生成規則には、参照しやすいように名前と番号の両方が付けられています。 可能な限り、基本的な構造は、それらを使用するより複雑な構造より前に、 “ボトムアップ” 方式で指定されます。

生成規則には、左右 2 ペインの並列形式で提示される例が伴います。 左側は YAML の例で、右側はその例の別の YAML ビューです。 右側のビューでは、可能な場合は JSON を使用します。 そうでない場合は、可能な限り JSON に近い YAML 形式を使用します。

4.1. 生成規則構文

生成規則は production-name ::= term という構文で定義されます。ここで term は次のいずれかです。

原子的項
  • 引用符付き文字列("abc")。 これは、その文字の連結に一致します。単一の文字は通常、単一引用符('a')で書かれます。
  • 16 進数(x0A)。 これは、その Unicode コードポイントの文字に一致します。
  • 16 進数の範囲([x20-x7E])。 これは、Unicode コードポイントがその範囲内にある 任意の文字に一致します。
  • 生成規則の名前(c-printable)。 これは、その生成規則に一致します。
先読み/後読み
  • [ lookahead = term ]。 これは、term が一致する場合に空文字列に一致します。
  • [ lookahead ≠ term ]。 これは、term が一致しない場合に 空文字列に一致します。
  • [ lookbehind = term ]。 これは、term が 行上の任意の先行位置から始まり、現在位置で終わる形で一致する場合に、空文字列に一致します。
特殊な生成規則
  • <start-of-line>。 これは行頭の空文字列に一致します。
  • <end-of-input>。 入力の終端の空文字列に一致します。
  • <empty>。 これは(常に)空文字列に一致します。
括弧で囲まれた項

その内容に一致します。

連結

term-one term-two であり、 term-one の後に term-two が続くものに一致します。

選択

term-one | term-two であり、 可能であれば term-one に一致し、 そうでなければ term-two に一致します。

量指定された項:
  • term?。 これは (term | <empty>) に一致します。
  • term*。 これは (term term* | <empty>) に一致します。
  • term+。 これは (term term*) に一致します。

注:量指定された項は常に貪欲です。

優先順位は、括弧、次に量指定、次に連結、最後に選択です。

生成規則定義内の一部の行には、次のようなコメントが含まれる場合があります。

production-a ::=
  production-b      # clarifying comment

これらのコメントは情報提供のみを目的としています。 たとえば、# not followed by non-ws char と書かれたコメントは、 その特定の生成規則の内容だけからは明らかでない場合でも、 実際の生成規則が記述されたとおりに振る舞うことを意識すべきだ、という意味にすぎません。

4.2. 生成規則パラメーター

一部の生成規則は、名前の後の括弧内にパラメーターを持ちます。たとえば s-line-prefix(n,c) です。 パラメーター化された生成規則は、各パラメーターに固定値を持つ(一無限の) 生成規則列の短縮表記です。

たとえば、この生成規則:

production-a(n) ::= production-b(n)

は次の短縮表記です。

production-a(0) ::= production-b(0)
production-a(1) ::= production-b(1)
…

また、この生成規則:

production-a(n) ::=
  ( production-b(n+m) production-c(n+m) )+

は次の短縮表記です。

production-a(0) ::=
    ( production-b(0) production-c(0) )+
  | ( production-b(1) production-c(1) )+
  | …
production-a(1) ::=
    ( production-b(1) production-c(1) )+
  | ( production-b(2) production-c(2) )+
  | …
…

パラメーターは次のとおりです。

インデント:n または m

0 を含む任意の自然数です。n は -1 であっても構いません。

コンテキスト:c

このパラメーターにより、生成規則は周囲に応じてその振る舞いを調整できます。 YAML は 2 つのコンテキスト群をサポートし、 ブロックスタイルフロースタイルを区別します。

次のいずれかの値を取ることができます。

  • BLOCK-IN – ブロック コンテキスト内
  • BLOCK-OUT – ブロック コンテキスト外
  • BLOCK-KEY – ブロック キーコンテキスト内
  • FLOW-IN – フロー コンテキスト内
  • FLOW-OUT – フロー コンテキスト外
  • FLOW-KEY – フローキー コンテキスト内
(ブロック)チョンピング:t

フロースカラーの改行チョンピング動作です。 次のいずれかの値を取ることができます。

  • STRIP – 末尾の改行をすべて 削除する
  • CLIP – 最初の 1 つを除いて末尾の改行をすべて 削除する
  • KEEP – 末尾の改行をすべて 保持する

4.3. 生成規則の命名規約

生成規則の組み合わせを追いやすくするため、生成規則名には 接頭辞形式の命名規約を使用します。 各生成規則には、それが開始および終了する文字の種類に基づく接頭辞が与えられます。

e-

文字に一致しない生成規則。

c-

特殊文字で開始し、特殊文字で終了する生成規則。

b-

単一の改行に一致する生成規則。

nb-

改行文字で開始し、非改行文字で終了する 生成規則。

s-

空白文字で開始し、空白文字で終了する 生成規則。

ns-

スペース文字で開始し、非スペース文字で終了する 生成規則。

l-

完全な行に一致する生成規則。

X-Y-

X- 文字で開始し、 Y- 文字で終了する生成規則。 ここで X-Y- は上記のいずれかの 接頭辞です。

X+X-Y+

上記と同様の生成規則で、さらに、一致した内容の インデントレベルが指定された n パラメーターより大きいという 追加プロパティを持つもの。

第5章 文字生成規則

5.1. 文字集合

可読性を保証するため、YAML ストリームは Unicode 文字集合の 印字可能な部分集合のみを使用します。 許可される文字範囲は、C0 制御ブロック15 x00-x1F(ただし許可される TAB x09、LF x0A、CR x0D を除く)、DEL x7F、C1 制御ブロック x80-x9F(ただし許可される NEL x85 を除く)、 サロゲートブロック16 xD800-xDFFFxFFFExFFFF を明示的に除外します。

入力時、YAML プロセッサーは、この印字可能な 部分集合内のすべての文字を受け入れなければなりません。

出力時、YAML プロセッサーは、この印字可能な 部分集合内の文字のみを生成しなければなりません。 この集合外の文字は、エスケープシーケンスを使用して 提示されなければなりません。 さらに、許可される文字のうち印字不能であることが知られているものも エスケープされるべきです。

注:これは必須ではありません。完全な実装には広範な文字プロパティ表が必要になるためです。

[1] c-printable ::=
                         # 8 bit
    x09                  # Tab (\t)
  | x0A                  # Line feed (LF \n)
  | x0D                  # Carriage Return (CR \r)
  | [x20-x7E]            # Printable ASCII
                         # 16 bit
  | x85                  # Next Line (NEL)
  | [xA0-xD7FF]          # Basic Multilingual Plane (BMP)
  | [xE000-xFFFD]        # Additional Unicode Areas
  | [x010000-x10FFFF]    # 32 bit

JSON 互換性を保証するため、YAML プロセッサーは、引用スカラー内で すべての非 C0 文字を許可しなければなりません。 可読性を保証するため、そのようなスカラー内であっても、出力時には印字不能文字を エスケープすべきです。

注:JSON の引用スカラーは複数行にまたがることも タブを含むこともできませんが、 YAML の引用スカラーは可能です。

[2] nb-json ::=
    x09              # Tab character
  | [x20-x10FFFF]    # Non-C0-control characters

注:生成規則名 nb-json は、 ここでは “non-break JSON compatible” を意味します。

5.2. 文字エンコーディング

この仕様で言及されるすべての文字は Unicode コードポイントです。 各コードポイントは、使用される文字エンコーディングに応じて 1 つ以上のバイトとして書かれます。 UTF-16 では、xFFFF を超える文字は サロゲートペアを使用して 4 バイトとして書かれることに注意してください。

文字エンコーディングは提示詳細であり、 内容情報を伝えるために使用してはなりません。

入力時、YAML プロセッサーは UTF-8 および UTF-16 の 文字エンコーディングをサポートしなければなりません。 JSON 互換性のため、UTF-32 エンコーディングも サポートしなければなりません。

文字ストリームバイト順マークで始まる場合、 文字エンコーディングは、そのバイト順マークによって示されるものとされます。 そうでない場合、ストリームは ASCII 文字で始まらなければなりません。 これにより、null(x00)文字のパターンから エンコーディングを推定できます。

バイト順マークは任意の文書の先頭に現れても構いませんが、 同じストリーム内のすべての 文書は同じ文字エンコーディングを使用しなければなりません。

JSON 互換性を許容するため、バイト順マークは 引用スカラー内でも許可されます。 可読性のため、そのような内容内のバイト順マークは、出力時に エスケープされるべきです。

したがって、ストリームの最初の数バイトを次の表の行と (順に)照合することで、エンコーディングを推定できます。

Byte0 Byte1 Byte2 Byte3 Encoding
明示的 BOM x00 x00 xFE xFF UTF-32BE
ASCII の最初の文字 x00 x00 x00 any UTF-32BE
明示的 BOM xFF xFE x00 x00 UTF-32LE
ASCII の最初の文字 any x00 x00 x00 UTF-32LE
明示的 BOM xFE xFF UTF-16BE
ASCII の最初の文字 x00 any UTF-16BE
明示的 BOM xFF xFE UTF-16LE
ASCII の最初の文字 any x00 UTF-16LE
明示的 BOM xEF xBB xBF UTF-8
既定 UTF-8

推奨される出力エンコーディングは UTF-8 です。 別のエンコーディングを使用する場合は、最初のストリーム文字が ASCII であっても、明示的なバイト順マークを使用することが推奨されます。

バイト順マークと Unicode 文字エンコーディング方式の詳細については、 Unicode FAQ17 を参照してください。

[3] c-byte-order-mark ::= xFEFF

例では、バイト順マーク文字は “” として表示されます。

例 5.1 バイト順マーク

# Comment only.

# This stream contains no
# documents, only comments.

凡例:

例 5.2 無効なバイト順マーク

- Invalid use of BOM

- Inside a document.
ERROR:
 A BOM must not appear
 inside a document.

5.3. 指示文字

指示子とは、特殊な意味を持つ文字です。

-” (x2D、ハイフン)は ブロックシーケンス項目を示します。

[4] c-sequence-entry ::= '-'

?” (x3F、疑問符)は マッピングキーを示します。

[5] c-mapping-key ::= '?'

:” (x3A、コロン)は マッピング値を示します。

[6] c-mapping-value ::= ':'

例 5.3 ブロック構造指示子

sequence:
- one
- two
mapping:
  ? sky
  : blue
  sea : green
{ "sequence": [
    "one",
    "two" ],
  "mapping": {
    "sky": "blue",
    "sea": "green" } }

,” (x2C、カンマ)は フローコレクション項目を終了します。

[7] c-collect-entry ::= ','

[” (x5B、左角括弧)は フローシーケンスを開始します。

[8] c-sequence-start ::= '['

]” (x5D、右角括弧)は フローシーケンスを終了します。

[9] c-sequence-end ::= ']'

{” (x7B、左波括弧)は フローマッピングを開始します。

[10] c-mapping-start ::= '{'

}” (x7D、右波括弧)は フローマッピングを終了します。

[11] c-mapping-end ::= '}'

例 5.4 フローコレクション指示子

sequence: [ one, two, ]
mapping: { sky: blue, sea: green }
{ "sequence": [ "one", "two" ],
  "mapping":
    { "sky": "blue", "sea": "green" } }

#” (x23、octothorpe、hash、sharp、pound、 number sign)はコメントを示します。

[12] c-comment ::= '#'

例 5.5 コメント指示子

# Comment only.

# This stream contains no
# documents, only comments.

凡例:

&” (x26、アンパサンド)は、 ノードのアンカープロパティを示します。

[13] c-anchor ::= '&'

*” (x2A、アスタリスク)は エイリアスノードを示します。

[14] c-alias ::= '*'

!” (x21、感嘆符)は、 ノードタグを指定するために使用されます。 これは、タグディレクティブおよびタグ プロパティで使用されるタグハンドルを示すため、 ローカルタグを示すため、そして非プレーンスカラー非固有タグとして使用されます。

[15] c-tag ::= '!'

例 5.6 ノードプロパティ指示子

anchored: !local &anchor value
alias: *anchor
{ "anchored": !local &A1 "value",
  "alias": *A1 }

凡例:

|” (7C、垂直バー)は リテラルブロックスカラーを示します。

[16] c-literal ::= '|'

>” (x3E、大なり)は 折り畳みブロックスカラーを示します。

[17] c-folded ::= '>'

例 5.7 ブロックスカラー指示子

literal: |
  some
  text
folded: >
  some
  text
{ "literal": "some\ntext\n",
  "folded": "some text\n" }

凡例:

'” (x27、アポストロフィ、単一引用符)は、 単一引用フロー スカラーを囲みます。

[18] c-single-quote ::= "'"

"” (x22、二重引用符)は、 二重引用フロースカラーを囲みます。

[19] c-double-quote ::= '"'

例 5.8 引用スカラー指示子

single: 'text'
double: "text"
{ "single": "text",
  "double": "text" }

%” (x25、パーセント)は ディレクティブ行を示します。

[20] c-directive ::= '%'

例 5.9 ディレクティブ指示子

%YAML 1.2
--- text
"text"

凡例:

@” (x40、アット)と “`” (x60、グレイヴアクセント)は、 将来使用のために予約されています。

[21] c-reserved ::=
    '@' | '`'

例 5.10 予約済み指示子の無効な使用

commercial-at: @text
grave-accent: `text
ERROR:
 Reserved indicators can't
 start a plain scalar.

任意の指示文字:

[22] c-indicator ::=
    c-sequence-entry    # '-'
  | c-mapping-key       # '?'
  | c-mapping-value     # ':'
  | c-collect-entry     # ','
  | c-sequence-start    # '['
  | c-sequence-end      # ']'
  | c-mapping-start     # '{'
  | c-mapping-end       # '}'
  | c-comment           # '#'
  | c-anchor            # '&'
  | c-alias             # '*'
  | c-tag               # '!'
  | c-literal           # '|'
  | c-folded            # '>'
  | c-single-quote      # "'"
  | c-double-quote      # '"'
  | c-directive         # '%'
  | c-reserved          # '@' '`'

[”、“]”、“{”、“}”、および “,” 指示子は、 フロー コレクション内の構造を示します。 したがって、いくつかの構文で曖昧さを避けるため、一部の場合では禁止されます。 これは、関連する生成規則によってケースごとに処理されます。

[23] c-flow-indicator ::=
    c-collect-entry     # ','
  | c-sequence-start    # '['
  | c-sequence-end      # ']'
  | c-mapping-start     # '{'
  | c-mapping-end       # '}'

5.4. 改行文字

YAML は次の ASCII 改行文字を認識します。

[24] b-line-feed ::= x0A
[25] b-carriage-return ::= x0D
[26] b-char ::=
    b-line-feed          # x0A
  | b-carriage-return    # X0D

フォームフィード(x0C)を含むその他すべての文字は、 非改行文字と見なされます。 これには、非 ASCII 改行である next line(x85)、line separator(x2028)、paragraph separator(x2029)も含まれることに注意してください。

YAML バージョン 1.1 は、上記の非 ASCII 改行文字を サポートしていました。 しかし JSON はサポートしていません。 したがって、JSON 互換性を保証するため、YAML は バージョン 1.2 以降、それらを非改行文字として扱います。 そのため、YAML 1.2 プロセッサーバージョン 1.1文書解析する場合、適切な警告とともに これらの改行を非改行文字として扱うべきです。

[27] nb-char ::=
  c-printable - b-char - c-byte-order-mark

改行は、システムによって異なる方法で解釈され、広く使用される複数の形式を持ちます。

[28] b-break ::=
    (
      b-carriage-return  # x0A
      b-line-feed
    )                    # x0D
  | b-carriage-return
  | b-line-feed

スカラー内容内の改行は、YAML プロセッサーによって正規化されなければなりません。 そのような各改行は、単一の改行文字として解析されなければなりません。 元の改行形式は提示 詳細であり、内容情報を伝えるために使用してはなりません。

[29] b-as-line-feed ::=
  b-break

スカラー内容の外では、YAML は任意の改行を使用して行を終了することを 許可します。

[30] b-non-content ::=
  b-break

出力時、YAML プロセッサーは、最も適切な 任意の規約で改行を出力できます。

例では、明確にするために改行が “” グリフを使用して 表示されることがあります。

例 5.11 改行文字

|
  Line break (no glyph)
  Line break (glyphed)
"Line break (no glyph)\nLine break (glyphed)\n"

凡例:

5.5. 空白文字

YAML は 2 つの空白文字、すなわちスペースタブを認識します。

[31] s-space ::= x20
[32] s-tab ::= x09
[33] s-white ::=
  s-space | s-tab

残りの(印字可能な)非改行文字は、非スペース文字と見なされます。

[34] ns-char ::=
  nb-char - s-white

例では、タブ文字は “” というグリフで表示されます。 スペース文字は、明確にするために “·” というグリフで表示されることがあります。

例 5.12 タブとスペース

# Tabs and spaces
quoted:·"Quoted "
block:|
··void main() {
··printf("Hello, world!\n");
··}
{ "quoted": "Quoted \t",
  "block": "void main()
    {\n\tprintf(\"Hello, world!\\n\");\n}\n" }

凡例:

5.6. その他の文字

YAML 構文生成規則は、次の追加の文字クラスを使用します。

数値用の 10 進数字:

[35] ns-dec-digit ::=
  [x30-x39]             # 0-9

エスケープシーケンス用の 16 進数字:

[36] ns-hex-digit ::=
    ns-dec-digit        # 0-9
  | [x41-x46]           # A-F
  | [x61-x66]           # a-f

ASCII 文字(アルファベット)文字:

[37] ns-ascii-letter ::=
    [x41-x5A]           # A-Z
  | [x61-x7A]           # a-z

識別子用の単語(英数字)文字:

[38] ns-word-char ::=
    ns-dec-digit        # 0-9
  | ns-ascii-letter     # A-Z a-z
  | '-'                 # '-'

タグ用の URI 文字。URI 仕様18で定義されます。

慣例として、許可された印字可能 ASCII 文字以外の URI 文字は、 まず UTF-8 でエンコードされ、次に各バイトが “%” 文字を使用してエスケープされます。 YAML プロセッサーは、そのようなエスケープされた文字を 展開してはなりません。 タグ文字は、YAML ストリーム内で 提示されたとおりに、処理を行わずに 正確に保持および比較されなければなりません。

[39] ns-uri-char ::=
    (
      '%'
      ns-hex-digit{2}
    )
  | ns-word-char
  | '#'
  | ';'
  | '/'
  | '?'
  | ':'
  | '@'
  | '&'
  | '='
  | '+'
  | '$'
  | ','
  | '_'
  | '.'
  | '!'
  | '~'
  | '*'
  | "'"
  | '('
  | ')'
  | '['
  | ']'

!” 文字は 名前付きタグハンドルの終端を示すために使用されます。したがって、 タグ短縮形内での使用は制限されます。 さらに、そのような短縮形には “[”、“]”、“{”、“}” および “,” 文字を含めてはなりません。 これらの文字はフロー コレクション構造との曖昧さを引き起こします。

[40] ns-tag-char ::=
    ns-uri-char
  - c-tag               # '!'
  - c-flow-indicator

5.7. エスケープ文字

すべての非印字可能文字はエスケープされなければなりません。 YAML エスケープシーケンスは、ほとんどの現代的なコンピューター 言語に共通する “\” 記法を使用します。 各エスケープシーケンスは、適切な Unicode 文字へ 解析されなければなりません。 元のエスケープシーケンスは提示 詳細であり、内容情報を伝えるために使用してはなりません。

エスケープシーケンスは二重引用 スカラー内でのみ解釈されることに注意してください。 他のすべてのスカラースタイルでは、 “\” 文字は特別な意味を持たず、 非印字可能文字は利用できません。

[41] c-escape ::= '\'

YAML エスケープシーケンスは C のエスケープシーケンスのスーパーセットです。

エスケープされた ASCII null(x00)文字。

[42] ns-esc-null ::= '0'

エスケープされた ASCII ベル(x07)文字。

[43] ns-esc-bell ::= 'a'

エスケープされた ASCII バックスペース(x08) 文字。

[44] ns-esc-backspace ::= 'b'

エスケープされた ASCII 水平タブ(x09) 文字。 これは、行頭または行末で、先頭または末尾のタブを 内容の一部にするために有用です。

[45] ns-esc-horizontal-tab ::=
  't' | x09

エスケープされた ASCII 改行(x0A) 文字。

[46] ns-esc-line-feed ::= 'n'

エスケープされた ASCII 垂直タブ(x0B) 文字。

[47] ns-esc-vertical-tab ::= 'v'

エスケープされた ASCII フォームフィード(x0C) 文字。

[48] ns-esc-form-feed ::= 'f'

エスケープされた ASCII 復帰(x0D) 文字。

[49] ns-esc-carriage-return ::= 'r'

エスケープされた ASCII エスケープ(x1B)文字。

[50] ns-esc-escape ::= 'e'

エスケープされた ASCII スペース(x20)文字。 これは、行頭または行末で、先頭または末尾のスペースを 内容の一部にするために有用です。

[51] ns-esc-space ::= x20

エスケープされた ASCII 二重引用符(x22)。

[52] ns-esc-double-quote ::= '"'

JSON 互換性のための、エスケープされた ASCII スラッシュ (x2F)。

[53] ns-esc-slash ::= '/'

エスケープされた ASCII バックスラッシュ(x5C)。

[54] ns-esc-backslash ::= '\'

エスケープされた Unicode next line(x85) 文字。

[55] ns-esc-next-line ::= 'N'

エスケープされた Unicode ノーブレークスペース(xA0)文字。

[56] ns-esc-non-breaking-space ::= '_'

エスケープされた Unicode line separator(x2028) 文字。

[57] ns-esc-line-separator ::= 'L'

エスケープされた Unicode paragraph separator(x2029)文字。

[58] ns-esc-paragraph-separator ::= 'P'

エスケープされた 8 ビット Unicode 文字。

[59] ns-esc-8-bit ::=
  'x'
  ns-hex-digit{2}

エスケープされた 16 ビット Unicode 文字。

[60] ns-esc-16-bit ::=
  'u'
  ns-hex-digit{4}

エスケープされた 32 ビット Unicode 文字。

[61] ns-esc-32-bit ::=
  'U'
  ns-hex-digit{8}

任意のエスケープ文字:

[62] c-ns-esc-char ::=
  c-escape         # '\'
  (
      ns-esc-null
    | ns-esc-bell
    | ns-esc-backspace
    | ns-esc-horizontal-tab
    | ns-esc-line-feed
    | ns-esc-vertical-tab
    | ns-esc-form-feed
    | ns-esc-carriage-return
    | ns-esc-escape
    | ns-esc-space
    | ns-esc-double-quote
    | ns-esc-slash
    | ns-esc-backslash
    | ns-esc-next-line
    | ns-esc-non-breaking-space
    | ns-esc-line-separator
    | ns-esc-paragraph-separator
    | ns-esc-8-bit
    | ns-esc-16-bit
    | ns-esc-32-bit
  )

例 5.13 エスケープ文字

- "Fun with \\"
- "\" \a \b \e \f"
- "\n \r \t \v \0"
- "\  \_ \N \L \P \
  \x41 \u0041 \U00000041"
[ "Fun with \\",
  "\" \u0007 \b \u001b \f",
  "\n \r \t \u000b \u0000",
  "\u0020 \u00a0 \u0085 \u2028 \u2029 A A A" ]

凡例:

例 5.14 無効なエスケープ文字

Bad escapes:
  "\c
  \xq-"
ERROR:
- c is an invalid escaped character.
- q and - are invalid hex digits.

第6章 構造生成規則

6.1. インデントスペース

YAML のブロックスタイルでは、構造は インデントによって決定されます。 一般に、インデントは行頭にある 0 個以上のスペース 文字として定義されます。

移植性を保つため、タブ文字は インデントに使用してはなりません。 異なるシステムはタブを異なる方法で扱うためです。 なお、ほとんどの現代的なエディターは、タブキーを押すと 適切な数のスペースが挿入されるように設定できます。

インデント量は提示 詳細であり、内容情報を 伝えるために使用してはなりません。

[63]
s-indent(0) ::=
  <empty>

# When n≥0
s-indent(n+1) ::=
  s-space s-indent(n)

ブロックスタイル構文は、その構文よりも インデントが浅い行に遭遇したときに終了します。 生成規則では、これを表すために “s-indent-less-than(n)” および “s-indent-less-or-equal(n)” という 記法を使用します。

[64]
s-indent-less-than(1) ::=
  <empty>

# When n≥1
s-indent-less-than(n+1) ::=
  s-space s-indent-less-than(n)
  | <empty>
[65]
s-indent-less-or-equal(0) ::=
  <empty>

# When n≥0
s-indent-less-or-equal(n+1) ::=
  s-space s-indent-less-or-equal(n)
  | <empty>

ノードは、その親ノードよりも深くインデントされなければなりません。 すべての兄弟ノードは、まったく同じインデントレベルを使用しなければなりません。 ただし、各兄弟ノード内容は、 独立してさらに深くインデントされても構いません。

例 6.1 インデントスペース

··# 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" ] } }

凡例:

  • s-indent(n)
  • 内容
  • 内容でもインデントでもない

ブロックコレクション項目を示すために使用される “-”、“?”、“:” 文字は、 人にはインデントの一部として認識されます。 これは、関連する生成規則によってケースごとに処理されます。

例 6.2 インデント指示子

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

凡例:

  • 総インデント
  • s-indent(n)
  • インデントとしての指示子

6.2. 分離スペース

インデントおよびスカラー内容の外では、 YAML は行内のトークン間の分離空白文字を使用します。 そのような空白には、安全に タブ文字を含めることができることに注意してください。

分離スペースは提示詳細であり、 内容情報を伝えるために使用してはなりません。

[66] s-separate-in-line ::=
    s-white+
  | <start-of-line>

例 6.3 分離スペース

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

凡例:

6.3. 行接頭辞

スカラー内容内では、各行は非内容行接頭辞で始まります。 この接頭辞には常にインデントが含まれます。 フロースカラースタイルでは、さらに先頭のすべての 空白も含まれ、 そこにはタブ文字が含まれる場合があります。

行接頭辞は提示詳細であり、 内容情報を伝えるために使用してはなりません。

[67]
s-line-prefix(n,BLOCK-OUT) ::= s-block-line-prefix(n)
s-line-prefix(n,BLOCK-IN)  ::= s-block-line-prefix(n)
s-line-prefix(n,FLOW-OUT)  ::= s-flow-line-prefix(n)
s-line-prefix(n,FLOW-IN)   ::= s-flow-line-prefix(n)
[68] s-block-line-prefix(n) ::=
  s-indent(n)
[69] s-flow-line-prefix(n) ::=
  s-indent(n)
  s-separate-in-line?

例 6.4 行接頭辞

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

6.4. 空行

空行は、非内容接頭辞の後に改行が続く行です。

[70] l-empty(n,c) ::=
  (
      s-line-prefix(n,c)
    | s-indent-less-than(n)
  )
  b-as-line-feed

空行の意味は、それが現れるスカラースタイルに依存します。 これは、関連する生成規則によってケースごとに処理されます。

例 6.5 空行

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

凡例:

6.5. 行の折り畳み

行の折り畳みにより、元の長い行の意味を保持しながら、 可読性のために長い行を分割できます。 改行の後に空行が続く場合、それはトリムされます。最初の 改行は破棄され、残りは内容として保持されます。

[71] b-l-trimmed(n,c) ::=
  b-non-content
  l-empty(n,c)+

そうでない場合(次の行がではない場合)、 改行は単一の スペースx20)に変換されます。

[72] b-as-space ::=
  b-break

折り畳まれる非空行は、上記いずれかの 改行で終わることができます。

[73] b-l-folded(n,c) ::=
  b-l-trimmed(n,c) | b-as-space

例 6.6 行の折り畳み

>-
  trimmed
··↓
·↓

  as
  space
"trimmed\n\n\nas space"

上記の規則は、折り畳みブロックスタイルスカラー フロースタイルの両方に共通します。 折り畳みは、次のようにこれらの場合を区別します。

ブロック折り畳み

折り畳みブロックスタイルでは、最後の 改行と末尾の空行チョンピングの対象となり、決して折り畳まれません。 さらに、先頭に空白を含むテキスト行の周囲の 改行には折り畳みは適用されません。 そのようなより深くインデントされた行は、 そのような先頭の空白だけで構成されてもよいことに 注意してください。

ブロック行折り畳み規則の組み合わせの効果として、各 “段落” は 1 行として解釈され、空行は改行として解釈され、 より深くインデントされた行の整形は 保持されます。

例 6.7 ブロック折り畳み

>
··foo·
·↓
··→·bar

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

凡例:

フロー折り畳み

フロースタイルにおける折り畳みは、 より緩やかな意味を提供します。 フロースタイルは通常、構造を伝えるために インデントではなく明示的な 指示子に依存します。 したがって、行内のテキストの前後にあるスペースは 提示 詳細であり、内容情報を伝えるために使用してはなりません。 そのようなスペースがすべて破棄されると、すべての改行は 例外なく折り畳まれます。

フロー行折り畳み規則の組み合わせの効果として、各 “段落” は 1 行として解釈され、空行は改行として解釈され、 テキストは内容情報に影響を与えずに自由に より深くインデントできます。

[74] s-flow-folded(n) ::=
  s-separate-in-line?
  b-l-folded(n,FLOW-IN)
  s-flow-line-prefix(n)

例 6.8 フロー折り畳み

"
··foo·
·
··→·bar

··baz "
" foo\nbar\nbaz "

凡例:

6.6. コメント

明示的なコメントは “#” 指示子で示されます。 コメントは提示詳細であり、 内容情報を伝えるために使用してはなりません。

コメントは、他のトークンから空白文字によって 分離されていなければなりません。

注:JSON 互換性を保証するため、YAML プロセッサーは、入力 ストリームの最後のコメント改行が 省略されることを許容しなければなりません。 ただし、これは多くのツールを混乱させるため、YAML プロセッサーは出力時に ストリームを明示的な改行で 終了すべきです。

[75] c-nb-comment-text ::=
  c-comment    # '#'
  nb-char*
[76] b-comment ::=
    b-non-content
  | <end-of-input>
[77] s-b-comment ::=
  (
    s-separate-in-line
    c-nb-comment-text?
  )?
  b-comment

例 6.9 分離されたコメント

key:····# Comment
  valueeof
{ "key": "value" }

スカラー内容の外では、コメントは インデントレベルに関係なく、単独の行に現れても構いません。 なお、スカラー内容の外では、空白文字だけを含む行は コメント行と見なされます。

[78] l-comment ::=
  s-separate-in-line
  c-nb-comment-text?
  b-comment

例 6.10 コメント行

··# Comment↓
···

# This stream contains no
# documents, only comments.

ほとんどの場合、行がコメントで終わることができるとき、YAML はその後に 追加のコメント行が続くことを許します。 唯一の例外は、ブロックスカラー ヘッダーを終了するコメントです。

[79] s-l-comments ::=
  (
      s-b-comment
    | <start-of-line>
  )
  l-comment*

例 6.11 複数行コメント

key:····# Comment↓
········# lines↓
  value

{ "key": "value" }

6.7. 分離行

暗黙キーは単一行に制限されます。 それ以外のすべての場合、YAML はトークンを複数行の(場合によっては空の) コメントで分離することを許します。

複数行コメント分離の後に続く構造は、適切に インデントされなければならないことに注意してください。 ただし、分離用のコメント行自体にはそのような制限はありません。

[80]
s-separate(n,BLOCK-OUT) ::= s-separate-lines(n)
s-separate(n,BLOCK-IN)  ::= s-separate-lines(n)
s-separate(n,FLOW-OUT)  ::= s-separate-lines(n)
s-separate(n,FLOW-IN)   ::= s-separate-lines(n)
s-separate(n,BLOCK-KEY) ::= s-separate-in-line
s-separate(n,FLOW-KEY)  ::= s-separate-in-line
[81] s-separate-lines(n) ::=
    (
      s-l-comments
      s-flow-line-prefix(n)
    )
  | s-separate-in-line

例 6.12 分離スペース

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

6.8. ディレクティブ

ディレクティブは YAML プロセッサーへの命令です。 この仕様は “YAML” と “TAG” の 2 つのディレクティブを定義し、 その他すべてのディレクティブを将来使用のために予約します。 私的ディレクティブを定義する方法はありません。 これは意図的なものです。

ディレクティブは提示詳細であり、 内容情報を伝えるために使用してはなりません。

[82] l-directive ::=
  c-directive            # '%'
  (
      ns-yaml-directive
    | ns-tag-directive
    | ns-reserved-directive
  )
  s-l-comments

各ディレクティブは、非インデント行に個別に指定され、 “%” 指示子で始まり、 ディレクティブ名とパラメーターのリストが続きます。 これらのパラメーターの意味は、具体的なディレクティブに依存します。 YAML プロセッサーは、未知のディレクティブを 適切な警告とともに無視すべきです。

[83] ns-reserved-directive ::=
  ns-directive-name
  (
    s-separate-in-line
    ns-directive-parameter
  )*
[84] ns-directive-name ::=
  ns-char+
[85] ns-directive-parameter ::=
  ns-char+

例 6.13 予約済みディレクティブ

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

6.8.1. “YAML” ディレクティブ

YAML” ディレクティブは、 文書が準拠する YAML のバージョンを指定します。 この仕様は、YAML 1.1 処理に関する推奨事項を含め、バージョン “1.2” を定義します。

バージョン 1.2 の YAML プロセッサーは、明示的な “%YAML 1.2” ディレクティブを持つ文書と、 “YAML” ディレクティブを欠く文書の両方を 受け入れなければなりません。 そのような文書は、1.2 バージョン仕様に準拠していると見なされます。 より高いマイナーバージョン(例: “%YAML 1.3”)を指定する “YAML” ディレクティブを持つ文書は、 適切な警告とともに処理すべきです。 より高いメジャーバージョン(例: “%YAML 2.0”)を指定する “YAML” ディレクティブを持つ文書は、 適切なエラーメッセージとともに拒否すべきです。

バージョン 1.2 の YAML プロセッサーは、明示的な “%YAML 1.1” ディレクティブを持つ 文書も受け入れなければなりません。 バージョン 1.2 は、JSON 互換性を保証する目的で定義された、 バージョン 1.1 のほぼスーパーセットであることに注意してください。 したがって、バージョン 1.2 のプロセッサーは、 バージョン 1.1 の文書を、 非互換点(非 ASCII 改行の扱い。上記参照)について警告を出しつつ、 バージョン 1.2 であるかのように処理すべきです。

[86] ns-yaml-directive ::=
  "YAML"
  s-separate-in-line
  ns-yaml-version
[87] ns-yaml-version ::=
  ns-dec-digit+
  '.'
  ns-dec-digit+

例 6.14 “YAML” ディレクティブ

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

同じ文書に複数の “YAML” ディレクティブを指定することは、 たとえ両方の出現が同じバージョン番号を与えていてもエラーです。

例 6.15 無効な繰り返し YAML ディレクティブ

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

6.8.2. “TAG” ディレクティブ

TAG” ディレクティブは、 ノードタグを指定するための タグ短縮形記法を確立します。 各 “TAG” ディレクティブは、 ハンドル接頭辞に関連付けます。 これにより、コンパクトで読みやすいタグ記法が可能になります。

[88] ns-tag-directive ::=
  "TAG"
  s-separate-in-line
  c-tag-handle
  s-separate-in-line
  ns-tag-prefix

例 6.16 “TAG” ディレクティブ

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

同じ文書内で同じハンドルに対して複数の “TAG” ディレクティブを指定することは、 たとえ両方の出現が同じ接頭辞を与えていてもエラーです。

例 6.17 無効な繰り返し TAG ディレクティブ

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

6.8.2.1. タグハンドル

タグハンドルは、影響を受けるタグ 短縮形の接頭辞と正確に一致します。 タグハンドルには 3 つのバリアントがあります。

[89] c-tag-handle ::=
    c-named-tag-handle
  | c-secondary-tag-handle
  | c-primary-tag-handle
プライマリハンドル

プライマリタグハンドルは、単一の “!” 文字です。 これにより、単一の “プライマリ” 名前空間に対して、 可能な限り最もコンパクトな記法を使用できます。 既定では、このハンドルに関連付けられる接頭辞は “!” です。 したがって、既定では、このハンドルを使用する短縮形ローカル タグとして解釈されます。

明示的な “TAG” ディレクティブを提供し、このハンドルに異なる接頭辞を関連付けることで、 既定の動作を上書きできます。 これは、単一の “TAG” ディレクティブを追加するだけで、 ローカルタグの使用からグローバルタグの使用へ円滑に移行する方法を提供します。

[90] c-primary-tag-handle ::= '!'

例 6.18 プライマリタグハンドル

# Private
!foo "bar"
...
# Global
%TAG ! tag:example.com,2000:app/
---
!foo "bar"
!<!foo> "bar"
---
!<tag:example.com,2000:app/foo> "bar"
セカンダリハンドル

セカンダリタグハンドルは “!!” と書かれます。 これにより、単一の “セカンダリ” 名前空間に対してコンパクトな記法を使用できます。 既定では、このハンドルに関連付けられる接頭辞は “tag:yaml.org,2002:” です。

明示的な “TAG” ディレクティブを提供し、このハンドルに異なる接頭辞を関連付けることで、 この既定の動作を上書きできます。

[91] c-secondary-tag-handle ::= "!!"

例 6.19 セカンダリタグハンドル

%TAG !! tag:example.com,2000:app/
---
!!int 1 - 3 # Interval, not integer
!<tag:example.com,2000:app/int> "1 - 3"
名前付きハンドル

名前付きタグハンドルは、空でない名前を “!” 文字で囲みます。 明示的な “TAG” ディレクティブが、その名前に何らかの接頭辞を関連付けていない限り、 ハンドル名をタグ短縮形内で使用してはなりません。

ハンドル名は提示 詳細であり、内容情報を 伝えるために使用してはなりません。 特に、YAML プロセッサーは、 解析が完了した後に ハンドル名を保持する必要はありません。

[92] c-named-tag-handle ::=
  c-tag            # '!'
  ns-word-char+
  c-tag            # '!'

例 6.20 タグハンドル

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

凡例:

6.8.2.2. タグ接頭辞

タグ接頭辞には 2 つのバリアントがあります。

[93] ns-tag-prefix ::=
  c-ns-local-tag-prefix | ns-global-tag-prefix
ローカルタグ接頭辞

接頭辞が “!” 文字で始まる場合、 ハンドルを使用する短縮形ローカルタグへ展開されます。 そのようなタグは意図的に有効な URI ではなく、その意味は アプリケーションに固有であることに注意してください。 特に、同じストリーム内の 2 つの文書が、同じ ローカルタグに異なる意味を割り当てる場合があります。

[94] c-ns-local-tag-prefix ::=
  c-tag           # '!'
  ns-uri-char*

例 6.21 ローカルタグ接頭辞

%TAG !m! !my-
--- # Bulb here
!m!light fluorescent
...
%TAG !m! !my-
--- # Color here
!m!light green
!<!my-light> "fluorescent"
---
!<!my-light> "green"
グローバルタグ接頭辞

接頭辞が “!” 以外の文字で始まる場合、 それは有効な URI 接頭辞でなければならず、少なくともスキームを含むべきです。 関連付けられたハンドルを使用する短縮形は、 グローバルに一意な URI タグへ展開され、その意味は アプリケーション間で一貫します。 特に、すべてのストリーム内のすべての文書は、 同じグローバルタグに同じ意味を割り当てなければなりません。

[95] ns-global-tag-prefix ::=
  ns-tag-char
  ns-uri-char*

例 6.22 グローバルタグ接頭辞

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

6.9. ノードプロパティ

ノードは、その内容に加えて、 アンカータグという 2 つの任意のプロパティを持つことができます。 ノードプロパティは、ノードの内容の前に任意の順序で指定できます。 いずれか一方、または両方を省略できます。

[96] c-ns-properties(n,c) ::=
    (
      c-ns-tag-property
      (
        s-separate(n,c)
        c-ns-anchor-property
      )?
    )
  | (
      c-ns-anchor-property
      (
        s-separate(n,c)
        c-ns-tag-property
      )?
    )

例 6.23 ノードプロパティ

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

6.9.1. ノードタグ

タグプロパティは、ノードによって提示される ネイティブデータ構造の型を識別します。 タグは “!” 指示子で示されます。

[97] c-ns-tag-property ::=
    c-verbatim-tag
  | c-ns-shorthand-tag
  | c-non-specific-tag
逐語タグ

タグは、“<” と “>” 文字で囲むことで逐語的に書くことができます。 この場合、YAML プロセッサーは逐語タグを そのままアプリケーションへ渡さなければなりません。 特に、逐語タグはタグ解決の対象ではありません。 逐語タグは “!”(ローカル タグ)で始まるか、有効な URI (グローバルタグ)でなければなりません。

[98] c-verbatim-tag ::=
  "!<"
  ns-uri-char+
  '>'

例 6.24 逐語タグ

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

凡例:

例 6.25 無効な逐語タグ

- !<!> foo
- !<$:?> bar
ERROR:
- Verbatim tags aren't resolved,
  so ! is invalid.
- The $:? tag is neither a global
  URI tag nor a local tag starting
  with '!'.
タグ短縮形

タグ短縮形は、有効なタグハンドルの後に、 空でない接尾辞が続くものです。 タグハンドルは、既定により、または “TAG” ディレクティブを使用することにより、 接頭辞に関連付けられていなければなりません。 結果として解析されたタグは、接頭辞と 接尾辞の連結であり、“!”(ローカル タグ)で始まるか、有効な URI( グローバルタグ)でなければなりません。

タグハンドルの選択は 提示詳細であり、 内容情報を伝えるために使用してはなりません。 特に、タグハンドル解析が完了した後に破棄されても構いません。

接尾辞には “!” 文字を含めてはなりません。 これにより、タグ短縮形が名前付きタグ ハンドルを持つものとして解釈されてしまうためです。 さらに、接尾辞には “[”、“]”、“{”、“}”、および “,” 文字を含めてはなりません。 これらの文字はフロー コレクション構造との曖昧さを引き起こします。 接尾辞で上記の制限文字のいずれかを指定する必要がある場合、 それらは “%” 文字を使用して エスケープされなければなりません。 この動作は URI 文字エスケープ規則 (具体的には URI RFC の 2.3 節)と一致します。

[99] c-ns-shorthand-tag ::=
  c-tag-handle
  ns-tag-char+

例 6.26 タグ短縮形

%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" ]

凡例:

例 6.27 無効なタグ短縮形

%TAG !e! tag:example,2000:app/
---
- !e! foo
- !h!bar baz
ERROR:
- The !e! handle has no suffix.
- The !h! handle wasn't declared.
非固有タグ

ノードがタグプロパティを持たない場合、 固有のものへ解決される必要がある 非固有タグが割り当てられます。 この非固有タグは、非プレーンスカラーでは “!” であり、 その他すべてのノードでは “?” です。 これは、ノードスタイル内容情報に 何らかの影響を与える唯一の場合です。

タグプロパティを明示的に “!” 非固有タグに設定することは可能です。 慣例により、この指定はタグ解決を “無効化” し、 ノードをその種別に応じて “tag:yaml.org,2002:seq”、 “tag:yaml.org,2002:map”、 または “tag:yaml.org,2002:str” として 解釈させます。

?” 非固有タグを明示的に指定する方法はありません。 これは意図的なものです。

[100] c-non-specific-tag ::= '!'

例 6.28 非固有タグ

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

凡例:

6.9.2. ノードアンカー

アンカーは “&” 指示子で示されます。 これは、将来参照するためにノードを標識します。 その後、エイリアスノードを使用して、 アンカー付けされたノードの追加の包含を示すことができます。 アンカー付けされたノードは、どのエイリアス ノードからも参照される必要はありません。特に、 すべてのノードがアンカー付けされていても妥当です。

[101] c-ns-anchor-property ::=
  c-anchor          # '&'
  ns-anchor-name

直列化詳細として、 アンカー名は直列化ツリー内に保持されることに注意してください。 ただし、それは表現グラフには反映されず、 内容情報を伝えるために使用してはなりません。 特に、YAML プロセッサーは、 表現構成された後に アンカー名を保持する必要はありません。

アンカー名には “[”、 “]”、“{”、“}”、および “,” 文字を含めてはなりません。 これらの文字はフロー コレクション構造との曖昧さを引き起こします。

[102] ns-anchor-char ::=
    ns-char - c-flow-indicator
[103] ns-anchor-name ::=
  ns-anchor-char+

例 6.29 ノードアンカー

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

第7章 フロースタイル生成規則

YAML のフロースタイルは、可読性のために長い内容行を折り畳むこと、構築されるネイティブデータ構造を制御するために ノードにタグ付けすること、そして構築済みオブジェクトインスタンスを 再利用するためにアンカーエイリアスを 使用することをカバーする、JSON の自然な拡張と考えることができます。

7.1. エイリアスノード

以前に直列化されたノードの後続の出現は、 エイリアスノードとして提示されます。 ノードの最初の出現は、後続の出現をエイリアスノードとして 提示できるように、 アンカーで標識されていなければなりません。

エイリアスノードは “*” 指示子で示されます。 エイリアスは、同じアンカーを持つ、 直前の最も近いノードを参照します。 エイリアスノードが、その文書内で以前に出現していない アンカーを使用することはエラーです。 どのエイリアスノードにも使用されないアンカーを指定することは エラーではありません。

エイリアスノードは、どのプロパティ内容も指定してはならないことに注意してください。 それらはノードの最初の出現ですでに指定されているためです。

[104] c-ns-alias-node ::=
  c-alias           # '*'
  ns-anchor-name

例 7.1 エイリアスノード

First occurrence: &anchor Foo
Second occurrence: *anchor
Override anchor: &anchor Bar
Reuse anchor: *anchor
{ "First occurrence": &A "Foo",
  "Override anchor": &B "Bar",
  "Second occurrence": *A,
  "Reuse anchor": *B }

7.2. 空ノード

YAML では、多くの場合にノード内容を省略できます。 空の内容を持つノードは、空の値を持つ プレーンスカラーであるかのように解釈されます。 そのようなノードは、一般に “null” 値へ解決されます。

[105] e-scalar ::= ""

例では、明確にするため、空のスカラーが “°” というグリフで表示されることがあります。 このグリフは実際の文字ではなく、文字ストリーム内の位置に 対応することに注意してください。

例 7.2 空の内容

{
  foo : !!str°,
  !!str° : bar,
}
{ "foo": "",
  "": "bar" }

凡例:

ノードのプロパティノード内容は どちらも任意です。 これにより、完全に空のノードが可能になります。 完全に空のノードは、その存在を示す何らかの明示的な指示の後に続く場合にのみ妥当です。

[106] e-node ::=
  e-scalar    # ""

例 7.3 完全に空のフローノード

{
  ? foo :°,
  °: bar,
}
{ "foo": null,
  null : "bar" }

凡例:

7.3. フロースカラースタイル

YAML は 3 つのフロースカラースタイルを提供します。すなわち 二重引用単一引用、および プレーン(非引用)です。 それぞれ、可読性と表現力の間で異なるトレードオフを提供します。

スカラースタイル提示詳細であり、 内容情報を伝えるために使用してはなりません。ただし、プレーン スカラータグ解決の目的で 区別されるという例外があります。

7.3.1. 二重引用スタイル

二重引用スタイルは “"” 指示子で囲むことで指定されます。 これは、“\エスケープシーケンスを使用することにより、 任意の文字列を表現できる唯一のスタイルです。 その代償として、“\” および “"” 文字をエスケープする必要があります。

[107] nb-double-char ::=
    c-ns-esc-char
  | (
        nb-json
      - c-escape          # '\'
      - c-double-quote    # '"'
    )
[108] ns-double-char ::=
  nb-double-char - s-white

二重引用スカラーは、暗黙キー内に 含まれる場合、単一行に制限されます。

[109] c-double-quoted(n,c) ::=
  c-double-quote         # '"'
  nb-double-text(n,c)
  c-double-quote         # '"'
[110]
nb-double-text(n,FLOW-OUT)  ::= nb-double-multi-line(n)
nb-double-text(n,FLOW-IN)   ::= nb-double-multi-line(n)
nb-double-text(n,BLOCK-KEY) ::= nb-double-one-line
nb-double-text(n,FLOW-KEY)  ::= nb-double-one-line
[111] nb-double-one-line ::=
  nb-double-char*

例 7.4 二重引用の暗黙キー

"implicit block key" : [
  "implicit flow key" : value,
 ]
{ "implicit block key":
  [ { "implicit flow key": "value" } ] }

複数行の二重引用スカラーでは、改行フロー行折り畳みの対象となり、末尾の 空白文字はすべて破棄されます。 改行文字をエスケープすることもできます。 この場合、エスケープされた改行内容から除外され、そのエスケープされた改行の前にある末尾の 空白文字は保持されます。 空白文字をエスケープできることと組み合わせることで、 二重引用行を任意の位置で分割できます。

[112] s-double-escaped(n) ::=
  s-white*
  c-escape         # '\'
  b-non-content
  l-empty(n,FLOW-IN)*
  s-flow-line-prefix(n)
[113] s-double-break(n) ::=
    s-double-escaped(n)
  | s-flow-folded(n)

例 7.5 二重引用の改行

"folded·↓
to a space,→↓
·↓
to a line feed, or·→\↓
·\·→non-content"
"folded to a space,\nto a line feed, or \t \tnon-content"

各行の先頭および末尾の空白文字はすべて 内容から除外されます。 したがって、各継続行は少なくとも 1 つの非スペース文字を 含んでいなければなりません。 空行がある場合、それは行の折り畳みの一部として消費されます。

[114] nb-ns-double-in-line ::=
  (
    s-white*
    ns-double-char
  )*
[115] s-double-next-line(n) ::=
  s-double-break(n)
  (
    ns-double-char nb-ns-double-in-line
    (
        s-double-next-line(n)
      | s-white*
    )
  )?
[116] nb-double-multi-line(n) ::=
  nb-ns-double-in-line
  (
      s-double-next-line(n)
    | s-white*
  )

例 7.6 二重引用の行

"·1st non-empty

·2nd non-empty·
3rd non-empty·"
" 1st non-empty\n2nd non-empty 3rd non-empty "

7.3.2. 単一引用スタイル

単一引用スタイルは “'” 指示子で囲むことで指定されます。 したがって、単一引用スカラー内では、そのような文字は繰り返す必要があります。 これは、単一引用スカラーで行われる唯一のエスケープ形式です。 特に、“\” および “"” 文字は自由に使用できます。 これにより、単一引用スカラーは印字可能文字に制限されます。 さらに、長い単一引用行を分割できるのは、スペース文字が非スペースに囲まれている場所だけです。

[117] c-quoted-quote ::= "''"
[118] nb-single-char ::=
    c-quoted-quote
  | (
        nb-json
      - c-single-quote    # "'"
    )
[119] ns-single-char ::=
  nb-single-char - s-white

例 7.7 単一引用文字

'here''s to "quotes"'
"here's to \"quotes\""

凡例:

単一引用スカラーは、暗黙キー内に 含まれる場合、単一行に制限されます。

[120] c-single-quoted(n,c) ::=
  c-single-quote    # "'"
  nb-single-text(n,c)
  c-single-quote    # "'"
[121]
nb-single-text(FLOW-OUT)  ::= nb-single-multi-line(n)
nb-single-text(FLOW-IN)   ::= nb-single-multi-line(n)
nb-single-text(BLOCK-KEY) ::= nb-single-one-line
nb-single-text(FLOW-KEY)  ::= nb-single-one-line
[122] nb-single-one-line ::=
  nb-single-char*

例 7.8 単一引用の暗黙キー

'implicit block key' : [
  'implicit flow key' : value,
 ]
{ "implicit block key":
  [ { "implicit flow key": "value" } ] }

先頭および末尾の空白文字はすべて 内容から除外されます。 したがって、各継続行は少なくとも 1 つの非スペース文字を 含んでいなければなりません。 空行がある場合、それは行の折り畳みの一部として消費されます。

[123] nb-ns-single-in-line ::=
  (
    s-white*
    ns-single-char
  )*
[124] s-single-next-line(n) ::=
  s-flow-folded(n)
  (
    ns-single-char
    nb-ns-single-in-line
    (
        s-single-next-line(n)
      | s-white*
    )
  )?
[125] nb-single-multi-line(n) ::=
  nb-ns-single-in-line
  (
      s-single-next-line(n)
    | s-white*
  )

例 7.9 単一引用の行

'·1st non-empty

·2nd non-empty·
3rd non-empty·'
" 1st non-empty\n2nd non-empty 3rd non-empty "

7.3.3. プレーンスタイル

プレーン(非引用)スタイルには識別用の指示子がなく、 いかなる形式のエスケープも提供しません。 したがって、これは最も読みやすく、最も制限が多く、最もコンテキストに 敏感なスタイルです。 制限された文字集合に加えて、プレーンスカラーは空であってはならず、 先頭または末尾の空白文字を含んではなりません。 長いプレーン行を分割できるのは、スペース文字が非スペースに囲まれている場所だけです。

プレーンスカラーは、ほとんどの指示子で始まってはなりません。 それは他の YAML 構文との曖昧さを引き起こすためです。 ただし、“:”、“?”、および “-指示子は、非スペースの “安全な” 文字が後に続く場合、最初の文字として使用できます。 その場合は曖昧さが生じないためです。

[126] ns-plain-first(c) ::=
    (
        ns-char
      - c-indicator
    )
  | (
      (
          c-mapping-key       # '?'
        | c-mapping-value     # ':'
        | c-sequence-entry    # '-'
      )
      [ lookahead = ns-plain-safe(c) ]
    )

プレーンスカラーには、“: ” および “ #” という文字の組み合わせを 決して含めてはなりません。 そのような組み合わせは、マッピングキー/値ペアおよび コメントとの曖昧さを引き起こします。 さらに、フローコレクション内、または 暗黙キーとして使用される場合、 プレーンスカラーには “[”、 “]”、“{”、“}”、および “,” 文字を含めてはなりません。 これらの文字はフロー コレクション構造との曖昧さを引き起こします。

[127]
ns-plain-safe(FLOW-OUT)  ::= ns-plain-safe-out
ns-plain-safe(FLOW-IN)   ::= ns-plain-safe-in
ns-plain-safe(BLOCK-KEY) ::= ns-plain-safe-out
ns-plain-safe(FLOW-KEY)  ::= ns-plain-safe-in
[128] ns-plain-safe-out ::=
  ns-char
[129] ns-plain-safe-in ::=
  ns-char - c-flow-indicator
[130] ns-plain-char(c) ::=
    (
        ns-plain-safe(c)
      - c-mapping-value    # ':'
      - c-comment          # '#'
    )
  | (
      [ lookbehind = ns-char ]
      c-comment          # '#'
    )
  | (
      c-mapping-value    # ':'
      [ lookahead = ns-plain-safe(c) ]
    )

例 7.10 プレーン文字

# Outside flow collection:
- ::vector
- ": - ()"
- Up, up, and away!
- -123
- https://example.com/foo#bar
# Inside flow collection:
- [ ::vector,
  ": - ()",
  "Up, up and away!",
  -123,
  https://example.com/foo#bar ]
[ "::vector",
  ": - ()",
  "Up, up, and away!",
  -123,
  "http://example.com/foo#bar",
  [ "::vector",
    ": - ()",
    "Up, up, and away!",
    -123,
    "http://example.com/foo#bar" ] ]

凡例:

プレーンスカラーは、暗黙キー内に 含まれる場合、さらに単一行に制限されます。

[131]
ns-plain(n,FLOW-OUT)  ::= ns-plain-multi-line(n,FLOW-OUT)
ns-plain(n,FLOW-IN)   ::= ns-plain-multi-line(n,FLOW-IN)
ns-plain(n,BLOCK-KEY) ::= ns-plain-one-line(BLOCK-KEY)
ns-plain(n,FLOW-KEY)  ::= ns-plain-one-line(FLOW-KEY)
[132] nb-ns-plain-in-line(c) ::=
  (
    s-white*
    ns-plain-char(c)
  )*
[133] ns-plain-one-line(c) ::=
  ns-plain-first(c)
  nb-ns-plain-in-line(c)

例 7.11 プレーンの暗黙キー

implicit block key : [
  implicit flow key : value,
 ]
{ "implicit block key":
  [ { "implicit flow key": "value" } ] }

先頭および末尾の空白文字はすべて 内容から除外されます。 したがって、各継続行は少なくとも 1 つの非スペース文字を 含んでいなければなりません。 空行がある場合、それは行の折り畳みの一部として消費されます。

[134] s-ns-plain-next-line(n,c) ::=
  s-flow-folded(n)
  ns-plain-char(c)
  nb-ns-plain-in-line(c)
[135] ns-plain-multi-line(n,c) ::=
  ns-plain-one-line(c)
  s-ns-plain-next-line(n,c)*

例 7.12 プレーン行

1st non-empty

·2nd non-empty·
3rd non-empty
"1st non-empty\n2nd non-empty 3rd non-empty"

7.4. フローコレクションスタイル

フローコレクションは、ブロック コレクション内に入れ子にされる([FLOW-OUT コンテキスト])か、別のフローコレクション内に入れ子にされる([FLOW-IN コンテキスト])か、または 暗黙キーの一部となる([FLOW-KEY コンテキスト] または [BLOCK-KEY コンテキスト])ことがあります。 フローコレクション項目は “,” 指示子で終了します。 最後の “,” は省略できます。 フローコレクション項目は決して完全に空には ならないため、これは曖昧さを引き起こしません。

[136]
in-flow(n,FLOW-OUT)  ::= ns-s-flow-seq-entries(n,FLOW-IN)
in-flow(n,FLOW-IN)   ::= ns-s-flow-seq-entries(n,FLOW-IN)
in-flow(n,BLOCK-KEY) ::= ns-s-flow-seq-entries(n,FLOW-KEY)
in-flow(n,FLOW-KEY)  ::= ns-s-flow-seq-entries(n,FLOW-KEY)

7.4.1. フローシーケンス

フローシーケンス内容は、“[” と “]” 文字で囲むことで示されます。

[137] c-flow-sequence(n,c) ::=
  c-sequence-start    # '['
  s-separate(n,c)?
  in-flow(n,c)?
  c-sequence-end      # ']'

シーケンス項目は “,” 文字で分離されます。

[138] ns-s-flow-seq-entries(n,c) ::=
  ns-flow-seq-entry(n,c)
  s-separate(n,c)?
  (
    c-collect-entry     # ','
    s-separate(n,c)?
    ns-s-flow-seq-entries(n,c)?
  )?

例 7.13 フローシーケンス

- [ one, two, ]
- [three ,four]
[ [ "one",
    "two" ],
  [ "three",
    "four" ] ]

任意のフローノードをフローシーケンス項目として使用できます。 さらに YAML は、フローシーケンス項目が単一のキー/値 ペアを持つマッピングである場合のために、 コンパクトな記法を提供します。

[139] ns-flow-seq-entry(n,c) ::=
  ns-flow-pair(n,c) | ns-flow-node(n,c)

例 7.14 フローシーケンス項目

[
"double
 quoted", 'single
           quoted',
plain
 text, [ nested ],
single: pair,
]
[ "double quoted",
  "single quoted",
  "plain text",
  [ "nested" ],
  { "single": "pair" } ]

7.4.2. フローマッピング

フローマッピングは、“{” と “}” 文字で囲むことで示されます。

[140] c-flow-mapping(n,c) ::=
  c-mapping-start       # '{'
  s-separate(n,c)?
  ns-s-flow-map-entries(n,in-flow(c))?
  c-mapping-end         # '}'

マッピング項目は “,” 文字で分離されます。

[141] ns-s-flow-map-entries(n,c) ::=
  ns-flow-map-entry(n,c)
  s-separate(n,c)?
  (
    c-collect-entry     # ','
    s-separate(n,c)?
    ns-s-flow-map-entries(n,c)?
  )?

例 7.15 フローマッピング

- { one : two , three: four , }
- {five: six,seven : eight}
[ { "one": "two",
    "three": "four" },
  { "five": "six",
    "seven": "eight" } ]

任意の “?” マッピングキー 指示子が指定されている場合、その項目の残りは 完全に空であっても構いません。

[142] ns-flow-map-entry(n,c) ::=
    (
      c-mapping-key    # '?' (not followed by non-ws char)
      s-separate(n,c)
      ns-flow-map-explicit-entry(n,c)
    )
  | ns-flow-map-implicit-entry(n,c)
[143] ns-flow-map-explicit-entry(n,c) ::=
    ns-flow-map-implicit-entry(n,c)
  | (
      e-node    # ""
      e-node    # ""
    )

例 7.16 フローマッピング項目

{
? explicit: entry,
implicit: entry,
?°°
}
{ "explicit": "entry",
  "implicit": "entry",
  null: null }

通常、YAML は “:” マッピング値 指示子がから空白分離されていることを要求します。 この制限の利点は、“:” 文字が 空白の後に続かない限り、 プレーンスカラー内で使用できることです。 これにより、引用符なしの URL やタイムスタンプが可能になります。 ただし、“a:1” がプレーン スカラーであり、 キー/値ペアではないため、混乱の原因にもなり得ます。

は、その存在が “:” によって 示されるため、完全に空であっても構わないことに 注意してください。

[144] ns-flow-map-implicit-entry(n,c) ::=
    ns-flow-map-yaml-key-entry(n,c)
  | c-ns-flow-map-empty-key-entry(n,c)
  | c-ns-flow-map-json-key-entry(n,c)
[145] ns-flow-map-yaml-key-entry(n,c) ::=
  ns-flow-yaml-node(n,c)
  (
      (
        s-separate(n,c)?
        c-ns-flow-map-separate-value(n,c)
      )
    | e-node    # ""
  )
[146] c-ns-flow-map-empty-key-entry(n,c) ::=
  e-node    # ""
  c-ns-flow-map-separate-value(n,c)
[147] c-ns-flow-map-separate-value(n,c) ::=
  c-mapping-value    # ':'
  [ lookahead ≠ ns-plain-safe(c) ]
  (
      (
        s-separate(n,c)
        ns-flow-node(n,c)
      )
    | e-node    # ""
  )

例 7.17 フローマッピングの分離値

{
unquoted·:·"separate",
https://foo.com,
omitted value:°,
°:·omitted key,
}
{ "unquoted": "separate",
  "http://foo.com": null,
  "omitted value": null,
  null: "omitted key" }

JSON 互換性を保証するため、フローマッピング内の キーJSON 風である場合、 YAML は後続のを “:” に 隣接して指定することを許します。 すべてのJSON 風キー指示子で囲まれているため、これは曖昧さを引き起こしません。 ただし、これは可読性を大きく低下させるため、YAML プロセッサーは、この場合でも出力時に を “:” から 分離すべきです。

[148] c-ns-flow-map-json-key-entry(n,c) ::=
  c-flow-json-node(n,c)
  (
      (
        s-separate(n,c)?
        c-ns-flow-map-adjacent-value(n,c)
      )
    | e-node    # ""
  )
[149] c-ns-flow-map-adjacent-value(n,c) ::=
  c-mapping-value          # ':'
  (
      (
        s-separate(n,c)?
        ns-flow-node(n,c)
      )
    | e-node    # ""
  )

例 7.18 フローマッピングの隣接値

{
"adjacent":value,
"readable"value,
"empty":°
}
{ "adjacent": "value",
  "readable": "value",
  "empty": null }

フローシーケンス内では、マッピング単一のキー/値ペアを含む場合、 よりコンパクトな記法を使用できます。 この記法では、周囲の “{” および “}” 文字は不要です。 この場合、マッピングに対してノードプロパティを 指定することはできないことに注意してください。

例 7.19 単一ペアのフローマッピング

[
foo: bar
]
[ { "foo": "bar" } ]

凡例:

?” 指示子が明示的に指定されている場合、 解析は曖昧でなく、構文は一般の場合と同一です。

[150] ns-flow-pair(n,c) ::=
    (
      c-mapping-key     # '?' (not followed by non-ws char)
      s-separate(n,c)
      ns-flow-map-explicit-entry(n,c)
    )
  | ns-flow-pair-entry(n,c)

例 7.20 単一ペアの明示的項目

[
? foo
 bar : baz
]
[ { "foo bar": "baz" } ]

?” 指示子が省略されている場合、 解析は、それを暗黙キーとして認識するために 暗黙キーの先を見なければなりません。 必要な先読み量を制限するため、“:” 指示子は キーの開始から最大 1024 個の Unicode 文字以内に現れなければなりません。 さらに、キーは単一行に制限されます。

YAML では任意のノードキーとして使用できることに注意してください。 特に、キーシーケンスまたは マッピングであっても構いません。 したがって、上記の制限がなければ、実用的なワンパス 解析は実装不可能だったでしょう。

[151] ns-flow-pair-entry(n,c) ::=
    ns-flow-pair-yaml-key-entry(n,c)
  | c-ns-flow-map-empty-key-entry(n,c)
  | c-ns-flow-pair-json-key-entry(n,c)
[152] ns-flow-pair-yaml-key-entry(n,c) ::=
  ns-s-implicit-yaml-key(FLOW-KEY)
  c-ns-flow-map-separate-value(n,c)
[153] c-ns-flow-pair-json-key-entry(n,c) ::=
  c-s-implicit-json-key(FLOW-KEY)
  c-ns-flow-map-adjacent-value(n,c)
[154] ns-s-implicit-yaml-key(c) ::=
  ns-flow-yaml-node(0,c)
  s-separate-in-line?
  /* At most 1024 characters altogether */
[155] c-s-implicit-json-key(c) ::=
  c-flow-json-node(0,c)
  s-separate-in-line?
  /* At most 1024 characters altogether */

例 7.21 単一ペアの暗黙項目

- [ YAML·: separate ]
- [ °: empty key entry ]
- [ {JSON: like}:adjacent ]
[ [ { "YAML": "separate" } ],
  [ { null: "empty key entry" } ],
  [ { { "JSON": "like" }: "adjacent" } ] ]

例 7.22 無効な暗黙キー

[ foo
 bar: invalid,
 "foo_...>1K characters..._bar": invalid ]
ERROR:
- The foo bar key spans multiple lines
- The foo...bar key is too long

7.5. フローノード

JSON 風フロースタイルはすべて、 明示的な開始および終了指示子を持ちます。 この性質を持たない唯一のフロースタイルプレーンスカラーです。 “JSON 風” スタイルのいずれも、実際には JSON として受け入れ可能ではないことに注意してください。 二重引用スタイルでさえ、JSON 文字列形式の スーパーセットです。

[156] ns-flow-yaml-content(n,c) ::=
  ns-plain(n,c)
[157] c-flow-json-content(n,c) ::=
    c-flow-sequence(n,c)
  | c-flow-mapping(n,c)
  | c-single-quoted(n,c)
  | c-double-quoted(n,c)
[158] ns-flow-content(n,c) ::=
    ns-flow-yaml-content(n,c)
  | c-flow-json-content(n,c)

例 7.23 フロー内容

- [ a, b ]
- { a: b }
- "a"
- 'b'
- c
[ [ "a", "b" ],
  { "a": "b" },
  "a",
  "b",
  "c" ]

完全なフローノードは、 任意のノードプロパティも持ちます。 ただし、アンカー付けされた ノードプロパティを参照するエイリアス ノードは例外です。

[159] ns-flow-yaml-node(n,c) ::=
    c-ns-alias-node
  | ns-flow-yaml-content(n,c)
  | (
      c-ns-properties(n,c)
      (
          (
            s-separate(n,c)
            ns-flow-yaml-content(n,c)
          )
        | e-scalar
      )
    )
[160] c-flow-json-node(n,c) ::=
  (
    c-ns-properties(n,c)
    s-separate(n,c)
  )?
  c-flow-json-content(n,c)
[161] ns-flow-node(n,c) ::=
    c-ns-alias-node
  | ns-flow-content(n,c)
  | (
      c-ns-properties(n,c)
      (
        (
          s-separate(n,c)
          ns-flow-content(n,c)
        )
        | e-scalar
      )
    )

例 7.24 フローノード

- !!str "a"
- 'b'
- &anchor "c"
- *anchor
- !!str°
[ "a",
  "b",
  "c",
  "c",
  "" ]

第8章 ブロックスタイル生成規則

YAML のブロックスタイルは、構造を示すために指示子ではなく インデントを使用します。 その結果、より人間に読みやすい(ただし、よりコンパクトではない)記法になります。

8.1. ブロックスカラースタイル

YAML は 2 つのブロックスカラースタイル、すなわちリテラル折り畳みを提供します。 それぞれ、可読性と表現力の間で異なるトレードオフを提供します。

8.1.1. ブロックスカラーヘッダー

ブロックスカラーは、内容そのものに先行するヘッダー内に与えられる、いくつかの 指示子によって制御されます。 このヘッダーの後には、任意のコメントを伴う非内容の 改行が続きます。 これは、コメントの後に追加の コメント行が続いてはならない唯一の場合です。

注:t 変数の定義については、 生成規則パラメーターを参照してください。

[162] c-b-block-header(t) ::=
  (
      (
        c-indentation-indicator
        c-chomping-indicator(t)
      )
    | (
        c-chomping-indicator(t)
        c-indentation-indicator
      )
  )
  s-b-comment

例 8.1 ブロックスカラーヘッダー

- | # Empty header↓
 literal
- >1 # Indentation indicator↓
 ·folded
- |+ # Chomping indicator↓
 keep

- >1- # Both indicators↓
 ·strip
[ "literal\n",
  " folded\n",
  "keep\n\n",
  " strip" ]

8.1.1.1. ブロックインデント指示子

すべてのブロックスカラーは内容インデントレベルを持ちます。 ブロックスカラーの内容は、各行の先頭にあるスペースのうち、 内容インデントレベルまでの数を除外します。

ブロックスカラーにインデント指示子がある場合、そのブロックスカラーの 内容インデントレベルは、ブロックスカラーのインデントレベルに インデント指示子文字の整数値を加えたものに等しくなります。

インデント指示子が与えられていない場合、内容インデントレベルは、内容の最初の非空行にある先頭のスペース数に 等しくなります。 非空行が存在しない場合、内容インデントレベルは 最長行のスペース数に等しくなります。

いずれかの非空行が、内容インデントレベル以上の数のスペースで 始まっていない場合、それはエラーです。

先頭の空行のいずれかが、最初の非空行より多くのスペースを 含むことはエラーです。

YAML プロセッサーは、検出が失敗する場合にのみ 明示的なインデント指示子を出力すべきです。

[163] c-indentation-indicator ::=
  [x31-x39]    # 1-9

例 8.2 ブロックインデント指示子

- |°
·detected
- >°
·
··
··# detected
- |1
··explicit
- >°
··detected
[ "detected\n",
  "\n\n# detected\n",
  " explicit\n",
  "\t\ndetected\n" ]

例 8.3 無効なブロックスカラーインデント指示子

- |
··
·text
- >
··text
·text
- |2
·text
ERROR:
- A leading all-space line must
  not have too many spaces.
- A following text line must
  not be less indented.
- The text is less indented
  than the indicated level.

8.1.1.2. ブロックチョンピング指示子

チョンピングは、最後の改行と 末尾の空行がどのように解釈されるかを制御します。 YAML は 3 つのチョンピング方式を提供します。

ストリップ

ストリッピングは “-” チョンピング指示子で指定されます。 この場合、最後の改行と末尾の 空行はすべて、 スカラーの内容から除外されます。

クリップ

クリッピングは、明示的なチョンピング指示子が指定されていない場合に使用される 既定の動作です。 この場合、最後の改行文字は スカラーの内容内に保持されます。 ただし、末尾の空行はすべて スカラーの内容から除外されます。

キープ

キーピングは “+” チョンピング指示子で指定されます。 この場合、最後の改行と末尾の 空行はすべて、 スカラーの内容の一部と見なされます。 これらの追加行は折り畳みの対象になりません。

使用されるチョンピング方式は提示 詳細であり、内容情報を伝えるために使用してはなりません。

[164]
c-chomping-indicator(STRIP) ::= '-'
c-chomping-indicator(KEEP)  ::= '+'
c-chomping-indicator(CLIP)  ::= ""

ブロックスカラーの最後の改行の解釈は、 ブロックスカラーヘッダーで指定された チョンピング指示子によって制御されます。

[165]
b-chomped-last(STRIP) ::= b-non-content  | <end-of-input>
b-chomped-last(CLIP)  ::= b-as-line-feed | <end-of-input>
b-chomped-last(KEEP)  ::= b-as-line-feed | <end-of-input>

例 8.4 最終改行のチョンピング

strip: |-
  text
clip: |
  text
keep: |+
  text
{ "strip": "text",
  "clip": "text\n",
  "keep": "text\n" }

ブロックスカラーに続く末尾の空行の解釈も、 ブロックスカラーヘッダーで指定された チョンピング指示子によって制御されます。

[166]
l-chomped-empty(n,STRIP) ::= l-strip-empty(n)
l-chomped-empty(n,CLIP)  ::= l-strip-empty(n)
l-chomped-empty(n,KEEP)  ::= l-keep-empty(n)
[167] l-strip-empty(n) ::=
  (
    s-indent-less-or-equal(n)
    b-non-content
  )*
  l-trail-comments(n)?
[168] l-keep-empty(n) ::=
  l-empty(n,BLOCK-IN)*
  l-trail-comments(n)?

明示的なコメント行は、末尾の空行の後に続いても構いません。 曖昧さを防ぐため、そのような最初のコメント行は、 ブロックスカラー内容より浅く インデントされていなければなりません。 追加のコメント行がある場合、それらにはそのような制限はありません。 これは、コメント行のインデントが 制約される唯一の場合です。

[169] l-trail-comments(n) ::=
  s-indent-less-than(n)
  c-nb-comment-text
  b-comment
  l-comment*

例 8.5 末尾行のチョンピング

# Strip
  # Comments:
strip: |-
  # text↓
··⇓
·# Clip
··# comments:

clip: |
  # text↓
·↓
·# Keep
··# comments:

keep: |+
  # text↓

·# Trail
··# comments.
{ "strip": "# text",
  "clip": "# text\n",
  "keep": "# text\n\n" }

ブロックスカラー空行だけで構成される場合、これらの行は 末尾行と見なされるため、チョンピングの影響を受けます。

例 8.6 空スカラーのチョンピング

strip: >-

clip: >

keep: |+

{ "strip": "",
  "clip": "",
  "keep": "\n" }

8.1.2. リテラルスタイル

リテラルスタイルは “|” 指示子で示されます。 これは最も単純で、最も制限が多く、最も読みやすいスカラースタイルです。

[170] c-l+literal(n) ::=
  c-literal                # '|'
  c-b-block-header(t)
  l-literal-content(n+m,t)

例 8.7 リテラルスカラー

|↓
·literal↓
·→text↓

"literal\n\ttext\n"

凡例:

リテラルスカラー内では、すべての(インデントされた)文字が 内容と見なされます。これには空白文字も 含まれます。 すべての改行文字は正規化されることに注意してください。 さらに、空行折り畳まれませんが、 最後の改行と末尾の 空行チョンピングされます。

リテラルスカラー内で文字をエスケープする方法はありません。 これにより、リテラルスカラーは印字可能文字に制限されます。 さらに、長いリテラル行を分割する方法はありません。

[171] l-nb-literal-text(n) ::=
  l-empty(n,BLOCK-IN)*
  s-indent(n) nb-char+
[172] b-nb-literal-next(n) ::=
  b-as-line-feed
  l-nb-literal-text(n)
[173] l-literal-content(n,t) ::=
  (
    l-nb-literal-text(n)
    b-nb-literal-next(n)*
    b-chomped-last(t)
  )?
  l-chomped-empty(n,t)

例 8.8 リテラル内容

|
·
··
··literal
···
··
··text·# Comment
"\n\nliteral\n·\n\ntext\n"

8.1.3. 折り畳みスタイル

折り畳みスタイルは “>” 指示子で示されます。 これはリテラルスタイルに似ていますが、折り畳みスカラーは 行の折り畳みの対象になります。

[174] c-l+folded(n) ::=
  c-folded                 # '>'
  c-b-block-header(t)
  l-folded-content(n+m,t)

例 8.9 折り畳みスカラー

>↓
·folded↓
·text↓

"folded text\n"

凡例:

折り畳みにより、単一のスペース文字が 2 つの非スペース文字を分離している任意の場所で、 長い行を分割できます。

[175] s-nb-folded-text(n) ::=
  s-indent(n)
  ns-char
  nb-char*
[176] l-nb-folded-lines(n) ::=
  s-nb-folded-text(n)
  (
    b-l-folded(n,BLOCK-IN)
    s-nb-folded-text(n)
  )*

例 8.10 折り畳み行

>

·folded
·line·next
·line↓
   * bullet

   * list
   * lines

·last
·line↓

# Comment
"\nfolded line\nnext line\n  \
* bullet\n \n  * list\n  \
* lines\n\nlast line\n"

(次の 3 つの例はこの例を複製し、それぞれ異なる生成規則を強調しています。)

空白文字で始まる行 (より深くインデントされた行)は 折り畳まれません。

[177] s-nb-spaced-text(n) ::=
  s-indent(n)
  s-white
  nb-char*
[178] b-l-spaced(n) ::=
  b-as-line-feed
  l-empty(n,BLOCK-IN)*
[179] l-nb-spaced-lines(n) ::=
  s-nb-spaced-text(n)
  (
    b-l-spaced(n)
    s-nb-spaced-text(n)
  )*

例 8.11 より深くインデントされた行

>

 folded
 line

 next
 line
···* bullet

···* list
···* lines↓

 last
 line

# Comment
"\nfolded line\nnext line\n  \
* bullet\n \n  * list\n  \
* lines\n\nlast line\n"

折り畳み行とより深くインデントされた行を分離する 改行および空行折り畳まれません。

[180] l-nb-same-lines(n) ::=
  l-empty(n,BLOCK-IN)*
  (
      l-nb-folded-lines(n)
    | l-nb-spaced-lines(n)
  )
[181] l-nb-diff-lines(n) ::=
  l-nb-same-lines(n)
  (
    b-as-line-feed
    l-nb-same-lines(n)
  )*

例 8.12 空の分離行

>

 folded
 line

 next
 line
   * bullet

   * list
   * lines

 last
 line

# Comment
"\nfolded line\nnext line\n  \
* bullet\n \n  * list\n  \
* lines\n\nlast line\n"

凡例:

最後の改行と、存在する場合の末尾の 空行は、チョンピングの 対象となり、決して折り畳まれません。

[182] l-folded-content(n,t) ::=
  (
    l-nb-diff-lines(n)
    b-chomped-last(t)
  )?
  l-chomped-empty(n,t)

例 8.13 最終空行

>

 folded
 line

 next
 line
   * bullet

   * list
   * lines

 last
 line

# Comment
"\nfolded line\nnext line\n  \
* bullet\n \n  * list\n  \
* lines\n\nlast line\n"

8.2. ブロックコレクションスタイル

可読性のため、ブロックコレクションスタイルはいかなる 指示子によっても示されません。 代わりに YAML は先読み方式を使用し、ブロックコレクションは キー/値ペアまたはシーケンス 項目が見つかった場合にのみ、プレーンスカラーと 区別されます。

8.2.1. ブロックシーケンス

ブロックシーケンスは単に一連のノードであり、それぞれが 先頭の “-” 指示子によって 示されます。 “-” 指示子は、 ノードから空白によって 分離されていなければなりません。 これにより、“-” の後に 非スペース文字が続く場合(例:“-42”)、 プレーンスカラーの最初の文字として使用できます。

[183] l+block-sequence(n) ::=
  (
    s-indent(n+1+m)
    c-l-block-seq-entry(n+1+m)
  )+
[184] c-l-block-seq-entry(n) ::=
  c-sequence-entry    # '-'
  [ lookahead ≠ ns-char ]
  s-l+block-indented(n,BLOCK-IN)

例 8.14 ブロックシーケンス

block sequence:
··- one↓
  - two : three↓
{ "block sequence": [
    "one",
    { "two": "three" } ] }

凡例:

項目のノードは、完全に空であっても、 入れ子のブロックノードであっても、 コンパクトな行内記法を使用しても構いません。 コンパクト記法は、その項目自体が入れ子のブロック コレクションである場合に使用できます。 この場合、“-” 指示子と 後続のスペースはどちらも、 入れ子のコレクションインデントの一部と見なされます。 そのようなコレクションに対して ノードプロパティを指定することはできないことに注意してください。

[185] s-l+block-indented(n,c) ::=
    (
      s-indent(m)
      (
          ns-l-compact-sequence(n+1+m)
        | ns-l-compact-mapping(n+1+m)
      )
    )
  | s-l+block-node(n,c)
  | (
      e-node    # ""
      s-l-comments
    )
[186] ns-l-compact-sequence(n) ::=
  c-l-block-seq-entry(n)
  (
    s-indent(n)
    c-l-block-seq-entry(n)
  )*

例 8.15 ブロックシーケンス項目の型

-° # Empty
- |
 block node
-·- one # Compact
··- two # sequence
- one: two # Compact mapping
[ null,
  "block node\n",
  [ "one", "two" ],
  { "one": "two" } ]

8.2.2. ブロックマッピング

ブロックマッピングは、一連の項目であり、各項目が キー/値ペア提示します。

[187] l+block-mapping(n) ::=
  (
    s-indent(n+1+m)
    ns-l-block-map-entry(n+1+m)
  )+

例 8.16 ブロックマッピング

block mapping:
·key: value↓
{ "block mapping": {
    "key": "value" } }

凡例:

?” 指示子が指定されている場合、 任意の値ノードは、“:” 指示子で示される別の行に指定しなければなりません。 なお YAML はここで、ブロックシーケンス項目について 上で説明したものと同じコンパクトな行内 記法を許可します。

[188] ns-l-block-map-entry(n) ::=
    c-l-block-map-explicit-entry(n)
  | ns-l-block-map-implicit-entry(n)
[189] c-l-block-map-explicit-entry(n) ::=
  c-l-block-map-explicit-key(n)
  (
      l-block-map-explicit-value(n)
    | e-node                        # ""
  )
[190] c-l-block-map-explicit-key(n) ::=
  c-mapping-key                     # '?' (not followed by non-ws char)
  s-l+block-indented(n,BLOCK-OUT)
[191] l-block-map-explicit-value(n) ::=
  s-indent(n)
  c-mapping-value                   # ':' (not followed by non-ws char)
  s-l+block-indented(n,BLOCK-OUT)

例 8.17 明示的なブロックマッピング項目

? explicit key # Empty value↓°
? |
  block key↓
:·- one # Explicit compact
··- two # block value↓
{ "explicit key": null,
  "block key\n": [
    "one",
    "two" ] }

?” 指示子が省略されている場合、 解析は、フローマッピング単一のキー/値ペアと 同じように、暗黙キーの先を見なければなりません。 したがって、そのようなキーは同じ制限を受けます。すなわち、 単一行に制限され、1024 個を超える Unicode 文字にまたがってはなりません。

[192] ns-l-block-map-implicit-entry(n) ::=
  (
      ns-s-block-map-implicit-key
    | e-node    # ""
  )
  c-l-block-map-implicit-value(n)
[193] ns-s-block-map-implicit-key ::=
    c-s-implicit-json-key(BLOCK-KEY)
  | ns-s-implicit-yaml-key(BLOCK-KEY)

この場合、暗黙キーと同じ行に指定できます。 ただし、ブロックマッピングでは、を “:” に隣接させてはならないことに 注意してください。これは可読性を大きく低下させ、フローマッピングの場合と 異なり、JSON 互換性のために必要ではないためです。

行内のに対するコンパクト記法はありません。 また、暗黙キーとそれに続く の両方が空であっても、 “:” 指示子は必須です。 これにより、複数行のプレーンスカラーとの潜在的な曖昧さを防ぎます。

[194] c-l-block-map-implicit-value(n) ::=
  c-mapping-value           # ':' (not followed by non-ws char)
  (
      s-l+block-node(n,BLOCK-OUT)
    | (
        e-node    # ""
        s-l-comments
      )
  )

例 8.18 暗黙的なブロックマッピング項目

plain key: in-line value
°:° # Both empty
"quoted key":
- entry
{ "plain key": "in-line value",
  null: null,
  "quoted key": [ "entry" ] }

コンパクトな行内記法も利用できます。 このコンパクト記法は、ブロックシーケンスおよび 明示的なブロックマッピング項目の内側に入れ子にできます。 そのような入れ子のマッピングに対してノードプロパティを 指定することはできないことに注意してください。

[195] ns-l-compact-mapping(n) ::=
  ns-l-block-map-entry(n)
  (
    s-indent(n)
    ns-l-block-map-entry(n)
  )*

例 8.19 コンパクトなブロックマッピング

- sun: yellow↓
- ? earth: blue↓
  : moon: white↓
[ { "sun": "yellow" },
  { { "earth": "blue" }:
      { "moon": "white" } } ]

8.2.3. ブロックノード

YAML では、フローノードブロックコレクション内に埋め込むことができます (ただし、その逆はできません)。 フローノードは、親の ブロックコレクションより少なくとも 1 つ多い スペースインデントされなければなりません。 なお、フローノードは後続の行で始まっても構いません。

この時点で、解析は、 プレーンスカラーと、入れ子の ブロックマッピングを開始する 暗黙キーとを区別する必要があります。

[196] s-l+block-node(n,c) ::=
    s-l+block-in-block(n,c)
  | s-l+flow-in-block(n)
[197] s-l+flow-in-block(n) ::=
  s-separate(n+1,FLOW-OUT)
  ns-flow-node(n+1,FLOW-OUT)
  s-l-comments

例 8.20 ブロックノード型

-
··"flow in block"↓>
 Block scalar↓!!map # Block collection
  foo : bar↓
[ "flow in block",
  "Block scalar\n",
  { "foo": "bar" } ]

ブロックノードのプロパティは複数行にまたがることができます。 この場合、それらはブロックコレクションより 少なくとも 1 つ多いスペースインデントされていなければなりません。 これはブロックコレクション項目の インデントとは無関係です。

[198] s-l+block-in-block(n,c) ::=
    s-l+block-scalar(n,c)
  | s-l+block-collection(n,c)
[199] s-l+block-scalar(n,c) ::=
  s-separate(n+1,c)
  (
    c-ns-properties(n+1,c)
    s-separate(n+1,c)
  )?
  (
      c-l+literal(n)
    | c-l+folded(n)
  )

例 8.21 ブロックスカラーノード

literal: |2
··value
folded:
···!foo
··>1
·value
{ "literal": "value",
  "folded": !<!foo> "value" }

人は “-” 指示子を インデントとして認識するため、入れ子の ブロックシーケンスは、それを補うために 1 つ少ないスペースインデントされても構いません。 もちろん、別のブロックシーケンスの内側に 入れ子にされている場合は例外です([BLOCK-OUT コンテキスト] と [BLOCK-IN コンテキスト])。

[200] s-l+block-collection(n,c) ::=
  (
    s-separate(n+1,c)
    c-ns-properties(n+1,c)
  )?
  s-l-comments
  (
      seq-space(n,c)
    | l+block-mapping(n)
  )
[201] seq-space(n,BLOCK-OUT) ::= l+block-sequence(n-1)
    seq-space(n,BLOCK-IN)  ::= l+block-sequence(n)

例 8.22 ブロックコレクションノード

sequence: !!seq
- entry
- !!seq
 - nested
mapping: !!map
 foo: bar
{ "sequence": [
    "entry",
    [ "nested" ] ],
  "mapping": { "foo": "bar" } }

第9章 文書ストリーム生成規則

9.1. 文書

YAML 文字ストリームは、複数の文書を含むことができます。 各文書は他の文書から完全に独立しています。

9.1.1. 文書接頭辞

文書の前には、文字エンコーディングと任意の コメント行を指定する接頭辞を置くことができます。 ストリーム内のすべての文書は同じ 文字エンコーディングを使用しなければならないことに注意してください。 ただし、ストリーム内の各文書について、 バイト順マークを使用して エンコーディングを再指定することは妥当です。

任意の接頭辞が存在しても、必ずしも実際の文書の存在を 示すわけではありません。

[202] l-document-prefix ::=
  c-byte-order-mark?
  l-comment*

例 9.1 文書接頭辞

⇔# Comment
# lines
Document
"Document"

凡例:

9.1.2. 文書マーカー

ディレクティブを使用すると、潜在的な曖昧さが生じます。 行頭に “%” 文字があることは妥当です (たとえば、プレーンスカラーの 2 行目の最初の 文字として)。 では、実際のディレクティブと、たまたま “%” 文字で始まる 内容行とを、どのように区別すればよいのでしょうか。

解決策は、ディレクティブの処理を制御するために、 2 つの特殊なマーカー行を使用することです。1 つは 文書の開始に、もう 1 つは終了に置かれます。

文書の開始では、“%” 文字で始まる行は ディレクティブであると見なされます。 (空である可能性のある)ディレクティブのリストは、 ディレクティブ終了 マーカー行によって終了します。 このマーカーに続く行では、“%” を最初の文字として安全に使用できます。

文書の終端では、文書終了マーカー行を使用して、 パーサーに再び ディレクティブの走査を開始するよう知らせます。

この任意の文書接尾辞が存在しても、必ずしも実際の後続 文書の存在を示すわけではありません。

したがって当然、実際の内容行は、これらのマーカーの いずれかで始まることを禁止されます。

[203] c-directives-end ::= "---"
[204] c-document-end ::=
  "..."    # (not followed by non-ws char)
[205] l-document-suffix ::=
  c-document-end
  s-l-comments
[206] c-forbidden ::=
  <start-of-line>
  (
      c-directives-end
    | c-document-end
  )
  (
      b-char
    | s-white
    | <end-of-input>
  )

例 9.2 文書マーカー

%YAML 1.2
---
Document
... # Suffix
"Document"

9.1.3. 裸文書

裸文書は、どのディレクティブ行または マーカー行でも始まりません。 そのような文書は、内容以外を含まないため非常に “clean” です。 この場合、最初の非コメント行は “%” を最初の文字として 始まってはなりません。

文書ノードは、親が -1 個の スペースインデントされているかのように インデントされます。 ノードはその親ノードより深く インデントされなければならないため、 これにより文書のノードは 0 個以上の スペースインデントできます。

[207] l-bare-document ::=
  s-l+block-node(-1,BLOCK-IN)
  /* Excluding c-forbidden content */

例 9.3 裸文書

Bare
document
...
# No document
...
|
%!PS-Adobe-2.0 # Not the first line
"Bare document"
---
"%!PS-Adobe-2.0\n"

凡例:

9.1.4. 明示的文書

明示的文書は、明示的なディレクティブ終了 マーカー行で始まりますが、 ディレクティブはありません。 文書の存在がこのマーカーによって示されるため、 文書自体は完全に空であっても 構いません。

[208] l-explicit-document ::=
  c-directives-end
  (
      l-bare-document
    | (
        e-node    # ""
        s-l-comments
      )
  )

例 9.4 明示的文書

---
{ matches
% : 20 }
...
---
# Empty
...
{ "matches %": 20 }
---
null

9.1.5. ディレクティブ文書

ディレクティブ文書は、いくつかのディレクティブで始まり、 その後に明示的なディレクティブ終了マーカー行が続きます。

[209] l-directive-document ::=
  l-directive+
  l-explicit-document

例 9.5 ディレクティブ文書

%YAML 1.2
--- |
%!PS-Adobe-2.0
...
%YAML 1.2
---
# Empty
...
"%!PS-Adobe-2.0\n"
---
null

9.2. ストリーム

YAML ストリームは、0 個以上の文書から構成されます。 後続の文書には、何らかの分離 マーカー行が必要です。 ある文書文書終了マーカー行で終了していない場合、 それに続く文書ディレクティブ終了マーカー行で始まらなければなりません。

[210] l-any-document ::=
    l-directive-document
  | l-explicit-document
  | l-bare-document
[211] l-yaml-stream ::=
  l-document-prefix*
  l-any-document?
  (
      (
        l-document-suffix+
        l-document-prefix*
        l-any-document?
      )
    | c-byte-order-mark
    | l-comment
    | l-explicit-document
  )*

例 9.6 ストリーム

Document
---
# Empty
...
%YAML 1.2
---
matches %: 20
"Document"
---
null
---
{ "matches %": 20 }

バイト列は、全体として上記の l-yaml-stream 生成規則に準拠している場合、 整形式ストリームです。

第10章 推奨スキーマ

YAML スキーマは、タグの集合と、 非固有タグ解決するための仕組みの組み合わせです。

10.1. フェイルセーフスキーマ

フェイルセーフスキーマは、任意の YAML 文書で動作することが保証されています。 したがって、これは汎用 YAML ツールに推奨される スキーマです。 そのため、YAML プロセッサーは、 少なくともオプションとして、このスキーマを サポートすべきです。

10.1.1. タグ

10.1.1.1. 汎用マッピング

URI

tag:yaml.org,2002:map

種別

マッピング

定義

連想コンテナーを表します。そこでは各 キーが関連付け内で一意であり、正確に 1 つの に対応付けられます。 YAML はキーの型に制限を課しません。特に、 スカラーに限定されません。 ネイティブ型への バインディングの例には、Perl のハッシュ、 Python の dictionary、Java の Hashtable があります。

例 10.1 !!map の例

Block style: !!map
  Clark : Evans
  Ingy  : döt Net
  Oren  : Ben-Kiki

Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki }

10.1.1.2. 汎用シーケンス

URI

tag:yaml.org,2002:seq

種別

シーケンス

定義

0 から始まる連続する整数でインデックス付けされたコレクションを 表しますネイティブ型への バインディングの例には、Perl の配列、 Python の list または tuple、Java の array または Vector があります。

例 10.2 !!seq の例

Block style: !!seq
- Clark Evans
- Ingy döt Net
- Oren Ben-Kiki

Flow style: !!seq [ Clark Evans, Ingy döt Net, Oren Ben-Kiki ]

10.1.1.3. 汎用文字列

URI

tag:yaml.org,2002:str

種別

スカラー

定義

Unicode 文字列、すなわち 0 個以上の Unicode 文字の列を 表します。 この型は通常、ネイティブ言語の 文字列型にバインドされます。 あるいは、そのような型を持たない言語(C など)では文字配列に バインドされます。

正準形式:

自明な形式。

例 10.3 !!str の例

Block style: !!str |-
  String: just a theory.

Flow style: !!str "String: just a theory."

10.1.2. タグ解決

!” 非固有タグを持つすべての ノードは、標準の慣例により、 その種別に応じて “tag:yaml.org,2002:seq”、 “tag:yaml.org,2002:map” または “tag:yaml.org,2002:str” に 解決されます。

?” 非固有タグを持つすべての ノードは、未解決のまま残されます。 これにより、アプリケーション部分的な表現を扱うことを求められます。

10.2. JSON スキーマ

JSON スキーマは、ほとんどの現代的なコンピューター言語に共通する 最小公分母であり、JSON ファイルの解析を 可能にします。 したがって、YAML プロセッサーは、 少なくともオプションとして、このスキーマを サポートすべきです。 また、他のスキーマもこれを基礎にすることが 強く推奨されます。

10.2.1. タグ

JSON スキーマは、 フェイルセーフスキーマで定義されるものに加えて、 次のタグを使用します。

10.2.1.1. Null

URI

tag:yaml.org,2002:null

種別

スカラー

定義

値が存在しないことを表します。 これは通常、ネイティブの null 風の値 (たとえば Perl の undef、 Python の None)に バインドされます。 null は空文字列とは異なることに注意してください。 また、何らかのキーと null を持つマッピング項目は妥当であり、 そのキーマッピング内に 存在しないこととは異なります。

正準形式

null

例 10.4 !!null の例

!!null null: value for null key
key with null value: !!null null

10.2.1.2. Boolean

URI

tag:yaml.org,2002:bool

種別

スカラー

定義

true/false 値を表しますネイティブの Boolean 型を持たない 言語(C など)では、通常、true に 1、false に 0 を使用して、 ネイティブ整数型にバインドされます。

正準形式

true または false のいずれか。

例 10.5 !!bool の例

YAML is a superset of JSON: !!bool true
Pluto is a planet: !!bool false

10.2.1.3. Integer

URI

tag:yaml.org,2002:int

種別

スカラー

定義

任意サイズの有限な数学的整数を表します。 この型のスカラーは、可能であればネイティブの整数データ型に バインドされるべきです。

一部の言語(Perl など)は、整数値と浮動小数点値の両方を許す “number” 型のみを提供します。 YAML プロセッサーは、適切にラウンドトリップできる限り、 そのような型を整数に使用しても構いません。

一部の言語(C など)では、整数がネイティブ型の記憶能力を オーバーフローする場合があります。 YAML プロセッサーは、そのような値をエラーとして拒否したり、 警告付きで切り詰めたり、あるいはラウンドトリップさせる別の方法を見つけても構いません。 一般に、32 個の二進数字で表現可能な整数は、多くのシステムを通じて安全に ラウンドトリップできるはずです。

正準形式

10 進整数表記。負の値には先頭に “-” 文字を付け、 正規表現 0 | -? [1-9] [0-9]* に一致します。

例 10.6 !!int の例

negative: !!int -12
zero: !!int 0
positive: !!int 34

10.2.1.4. Floating Point

URI

tag:yaml.org,2002:float

種別

スカラー

定義

実数の近似値を表します。 これには 3 つの特殊値(正の無限大、負の無限大、“not a number”)が含まれます。

一部の言語(Perl など)は、整数値と浮動小数点値の両方を許す “number” 型のみを提供します。 YAML プロセッサーは、適切にラウンドトリップできる限り、 そのような型を浮動小数点数に使用しても構いません。

すべての浮動小数点値を、任意のネイティブ型に正確に格納できるわけではありません。 したがって、float 値はラウンドトリップ時に “小さな量” だけ変化する場合があります。 サポートされる範囲と精度は実装に依存しますが、32 ビット IEEE float は安全なはずです。 YAML は特定の精度を指定しないため、浮動小数点の マッピングキーを使用するには細心の注意が必要であり、推奨されません。

正準形式

0.inf-.inf.nan のいずれか、または 次の正規表現に一致する科学的記数法。
-? [1-9] ( \. [0-9]* [1-9] )? ( e [-+] [1-9] [0-9]* )?.

例 10.7 !!float の例

negative: !!float -1
zero: !!float 0
positive: !!float 2.3e4
infinity: !!float .inf
not a number: !!float .nan

10.2.2. タグ解決

JSON スキーマタグ解決は、 フェイルセーフスキーマタグ解決の拡張です。

!” 非固有タグを持つすべての ノードは、標準の慣例により、 その種別に応じて “tag:yaml.org,2002:seq”、 “tag:yaml.org,2002:map” または “tag:yaml.org,2002:str” に 解決されます。

?” 非固有タグを持つ コレクション(すなわちタグなしコレクション)は、その種別に応じて “tag:yaml.org,2002:seq” または “tag:yaml.org,2002:map” に 解決されます。

?” 非固有タグを持つ スカラー(すなわちプレーンスカラー)は、 正規表現のリストと照合されます(最初に一致したものが採用されます。たとえば 0!!int として解決されます)。 原則として、JSON ファイルには、これらの少なくとも 1 つに一致しない スカラーは含まれないはずです。 したがって、YAML プロセッサーは、 それらをエラーと見なすべきです。

正規表現 解決先タグ
null tag:yaml.org,2002:null
true | false tag:yaml.org,2002:bool
-? ( 0 | [1-9] [0-9]* ) tag:yaml.org,2002:int
-? ( 0 | [1-9] [0-9]* ) ( \. [0-9]* )? ( [eE] [-+]? [0-9]+ )? tag:yaml.org,2002:float
* エラー

注:float の正規表現は、 JSON 仕様のものとは正確には一致しません。JSON 仕様では、ドットの後に少なくとも 1 桁が必要です:( \. [0-9]+ )。YAML 1.2 仕様は JSON の動作に一致することを意図していましたが、 これは 1.2.2 仕様では対処できません。

例 10.8 JSON タグ解決

A null: null
Booleans: [ true, false ]
Integers: [ 0, -0, 3, -19 ]
Floats: [ 0., -0.0, 12e03, -2E+05 ]
Invalid: [ True, Null,
  0o7, 0x3A, +12.3 ]
{ "A null": null,
  "Booleans": [ true, false ],
  "Integers": [ 0, 0, 3, -19 ],
  "Floats": [ 0.0, -0.0, 12000, -200000 ],
  "Invalid": [ "True", "Null",
    "0o7", "0x3A", "+12.3" ] }

10.3. コアスキーマ

コアスキーマJSON スキーマの拡張であり、 同じ型をより人間に読みやすい形で 提示できるようにします。 これは、YAML プロセッサーが特に指示されない限り 使用すべき推奨の既定スキーマです。 また、他のスキーマもこれを基礎にすることが 強く推奨されます。

10.3.1. タグ

コアスキーマは、 JSON スキーマと同じタグを使用します。

10.3.2. タグ解決

コアスキーマタグ解決は、 JSON スキーマタグ解決の拡張です。

!” 非固有タグを持つすべての ノードは、標準の慣例により、 その種別に応じて “tag:yaml.org,2002:seq”、 “tag:yaml.org,2002:map” または “tag:yaml.org,2002:str” に 解決されます。

?” 非固有タグを持つ コレクション(すなわちタグなしコレクション)は、その種別に応じて “tag:yaml.org,2002:seq” または “tag:yaml.org,2002:map” に 解決されます。

?” 非固有タグを持つ スカラー(すなわちプレーンスカラー)は、 拡張された正規表現のリストと照合されます。 ただし、この場合、どの正規表現にも一致しなければ、そのスカラーtag:yaml.org,2002:str解決されます(すなわち、文字列と見なされます)。

正規表現 解決先タグ
null | Null | NULL | ~ tag:yaml.org,2002:null
/* Empty */ tag:yaml.org,2002:null
true | True | TRUE | false | False | FALSE tag:yaml.org,2002:bool
[-+]? [0-9]+ tag:yaml.org,2002:int(10 進)
0o [0-7]+ tag:yaml.org,2002:int(8 進)
0x [0-9a-fA-F]+ tag:yaml.org,2002:int(16 進)
[-+]? ( \. [0-9]+ | [0-9]+ ( \. [0-9]* )? ) ( [eE] [-+]? [0-9]+ )? tag:yaml.org,2002:float(数値)
[-+]? ( \.inf | \.Inf | \.INF ) tag:yaml.org,2002:float(無限大)
\.nan | \.NaN | \.NAN tag:yaml.org,2002:float(Not a number)
* tag:yaml.org,2002:str(既定)

例 10.9 コアタグ解決

A null: null
Also a null: # Empty
Not a null: ""
Booleans: [ true, True, false, FALSE ]
Integers: [ 0, 0o7, 0x3A, -19 ]
Floats: [
  0., -0.0, .5, +12e03, -2E+05 ]
Also floats: [
  .inf, -.Inf, +.INF, .NAN ]
{ "A null": null,
  "Also a null": null,
  "Not a null": "",
  "Booleans": [ true, true, false, false ],
  "Integers": [ 0, 7, 58, -19 ],
  "Floats": [
    0.0, -0.0, 0.5, 12000, -200000 ],
  "Also floats": [
    Infinity, -Infinity, Infinity, NaN ] }

10.4. その他のスキーマ

上記の推奨スキーマはいずれも、任意の明示的な タグの使用を妨げません。 したがって、特定のプログラミング言語向けの YAML プロセッサーは通常、その言語の ネイティブデータ 構造に直接対応する何らかの形のローカルタグ (例:!ruby/object:Set)を提供します。

そのようなローカルタグはアドホックな アプリケーションには有用ですが、 安定した相互運用可能な、アプリケーション横断または プラットフォーム横断のデータ交換には十分ではありません。

相互運用可能なスキーマは、異なるプログラミング言語間で 同じデータを表す グローバルタグ(URI)を使用します。 さらに、相互運用可能なスキーマは追加の タグ解決規則を提供しても構いません。 そのような規則は、追加の正規表現を提供したり、 ノードへのパスを考慮したりできます。 これにより、相互運用可能なスキーマタグなしノードを使用できます。

そのようなスキーマは、上で定義した コアスキーマを基礎にすることが強く推奨されます。

参照リンク