7. Maps
Readable Object Notation
A map, called an object in JSON, contains string keys paired with values.
Any value may appear after a key, including null, another map, or a list.
An empty map is written {}.
Compact maps alternate keys and values, separated by whitespace. Each ordinary member has both a key and a value. A tag group supplies boolean members using the shorthand described below. There is no colon between a key and its value.
Canonical nonempty nested maps put the first key/value pair immediately after
{ and align each following pair beneath it. Each pair occupies its own line,
including in maps with one member. A comment that must precede the first item
puts the opening brace on its own line. The empty map remains {}:
single {x 1} multiple {x 1 y 2} empty {}
empty {} multiple {x 1 y 2} single {x 1}
{
"single": {
"x": 1
},
"multiple": {
"x": 1,
"y": 2
},
"empty": {}
}
{name Ada age 36 active true}
<active> age 36 name Ada
{
"name": "Ada",
"age": 36,
"active": true
}
A map with { alone on its opening line has one ordinary member per line and may also contain tag groups.
Each ordinary member begins with its key, followed by its value.
The first member may follow the opening brace on the same line, and the last value may be followed immediately by the closing brace.
{ name Ada Lovelace age 36 active true}
<active> age 36 name Ada Lovelace
{
"name": "Ada Lovelace",
"age": 36,
"active": true
}
When the first member follows { on the opening line, the map is packed:
each line contains whitespace-separated key/value pairs and optional tag groups.
A packed map can wrap between complete pairs. Values containing spaces need quotes.
settings { <active !admin> field00 value00 field01 value01 field02 value02 field03 value03 field04 value04 field05 value05 field06 value06 field07 value07 field08 value08 field09 value09 field10 value10 field11 value11 field12 value12 field13 value13 field14 value14 field15 value15 field16 value16 field17 value17 field18 value18 field19 value19 }
settings {<active !admin> field00 value00 field01 value01 field02 value02 field03 value03 field04 value04 field05 value05 field06 value06 field07 value07 field08 value08 field09 value09 field10 value10 field11 value11 field12 value12 field13 value13 field14 value14 field15 value15 field16 value16 field17 value17 field18 value18 field19 value19}
{
"settings": {
"active": true,
"admin": false,
"field00": "value00",
"field01": "value01",
"field02": "value02",
"field03": "value03",
"field04": "value04",
"field05": "value05",
"field06": "value06",
"field07": "value07",
"field08": "value08",
"field09": "value09",
"field10": "value10",
"field11": "value11",
"field12": "value12",
"field13": "value13",
"field14": "value14",
"field15": "value15",
"field16": "value16",
"field17": "value17",
"field18": "value18",
"field19": "value19"
}
}
A tag group also counts as content on the opening line. Its position selects
how the ordinary member lines are read. With { alone on the opening line,
the whole bare value Ada Lovelace PhD belongs to name:
settings { <active> name Ada Lovelace PhD }
settings {<active> name "Ada Lovelace PhD"}
{
"settings": {
"active": true,
"name": "Ada Lovelace PhD"
}
}
Moving the tag group after { selects packed mode. The same following line
now contains two pairs: name is Ada, and Lovelace is PhD:
settings {<active> name Ada Lovelace PhD }
settings {<active> Lovelace PhD name Ada}
{
"settings": {
"active": true,
"name": "Ada",
"Lovelace": "PhD"
}
}
To keep Ada Lovelace PhD as one value in packed mode, write it as
"Ada Lovelace PhD". Canonical formatting chooses a layout from the decoded
map rather than the input layout, while preserving the decoded values.
A map can also pack a compact nested value alongside its other members:
data { count 3 values [1 2 3] name Ada }
data {count 3 name Ada values [1 2 3]}
{
"data": {
"count": 3,
"values": [
1,
2,
3
],
"name": "Ada"
}
}
In canonical output, every ordinary key/value pair has its own line, in sorted key order. The first item follows the opening brace, and subsequent items align beneath it. A tag group has its own line before ordinary members:
record { field00 value00 field01 value01 field02 value02 field03 value03 field04 value04 field05 value05 field06 value06 field07 value07 field08 value08 field09 value09 field10 value10 }
record {field00 value00 field01 value01 field02 value02 field03 value03 field04 value04 field05 value05 field06 value06 field07 value07 field08 value08 field09 value09 field10 value10}
{
"record": {
"field00": "value00",
"field01": "value01",
"field02": "value02",
"field03": "value03",
"field04": "value04",
"field05": "value05",
"field06": "value06",
"field07": "value07",
"field08": "value08",
"field09": "value09",
"field10": "value10"
}
}
This also applies when all the ordinary members would fit beside the tags:
user {<active> age 36 name Ada}
user {<active> age 36 name Ada}
{
"user": {
"active": true,
"age": 36,
"name": "Ada"
}
}
This is the same map as the following compact form:
{name "Ada Lovelace" age 36 active true}
<active> age 36 name Ada Lovelace
{
"name": "Ada Lovelace",
"age": 36,
"active": true
}
Keys are strings, so punctuation and spaces may be part of a key when it is quoted. The empty string is also a valid key.
{"full name" Ada "a:b" 1 "a,b" 2 "" empty}
"" empty "a,b" 2 a:b 1 "full name" Ada
{
"full name": "Ada",
"a:b": 1,
"a,b": 2,
"": "empty"
}
Keys are always read as strings. Number, boolean, and null spellings have no special meaning in key position.
{null 456 true omg 1 one ^name text}
1 one ^name text null 456 true omg
{
"null": 456,
"true": "omg",
"1": "one",
"^name": "text"
}
Bare keys follow different token rules from bare values.
A bare key runs to the whitespace before its value.
It cannot contain commas or double quotes, or begin with [, ], {, }, or <.
Brackets after the first character are part of the key. Parentheses do not
introduce a RON container and may begin a bare key.
Colons are ordinary characters in bare keys.
Each of these keys starts with a comma, double quote, bracket, brace, or tag-group opener and must be quoted. The quote is part of the second key's name; JSON-style escaping is accepted in the input, and canonical formatting chooses a fence:
",name" 1 "\"name" 2 "[name" 3 "]name" 4 "{name" 5 "}name" 6 "<name" 7
""\"name"" 2 ",name" 1 "<name" 7 "[name" 3 "]name" 4 "{name" 5 "}name" 6
{
",name": 1,
"\"name": 2,
"[name": 3,
"]name": 4,
"{name": 5,
"}name": 6,
"<name": 7
}
items[0] 1 /people/{id} {get x} a:b colon
/people/{id} {get x} a:b colon items[0] 1
{
"items[0]": 1,
"/people/{id}": {
"get": "x"
},
"a:b": "colon"
}
Keys must be unique within a map. Repeated keys are errors, even when their values agree or one occurrence is written as a tag. Canonical formatting sorts members by key name, with boolean members collected into a tag group before the remaining members. These rules apply recursively to nested maps.
{name Ada age 36 active true}
<active> age 36 name Ada
{
"name": "Ada",
"age": 36,
"active": true
}