Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a complex mapping key in YAML?

Tags:

yaml

On the YAML specs there is a paragraph 2.11 about the question mark:

A question mark and space (“? ”) indicate a complex mapping key. Within a block collection, key: value pairs can start immediately following the dash, colon, or question mark.

This example is given:

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

This other example also fail to be converted to XML:

%YAML 1.2 - - - !!map {   ? !!str "Not indented"   : !!map {       ? !!str "By one space"       : !!str "By four\n  spaces\n",       ? !!str "Flow style"       : !!seq [           !!str "By two",           !!str "Also by two",           !!str "Still by two",         ]     } } 

Unfortunately I don't understand what does it means. I tried to convert this to XML using codebeautify, but I get an error.

So my question is:

What does the question mark do?

like image 863
nowox Avatar asked Nov 29 '15 19:11

nowox


People also ask

What is a complex mapping key indicated with in YAML?

A question mark and space (“? ”) indicate a complex mapping key. Within a block collection, key: value pairs can start immediately following the dash, colon, or question mark.

What does a mapping refer to in YAML?

Advertisements. Flow mappings in YAML represent the unordered collection of key value pairs. They are also called as mapping node. Note that keys should be maintained unique. If there is a duplication of keys in flow mapping structure, it will generate an error.

Can YAML Key have spaces?

Spaces are allowed in keys according to the specification and for those you don't need quotes (double or single, each with their own use). It is just a scalar string containing a space.

Which of the following types are used for YAML tag repository?

Representation. YAML represents the data structure using three kinds of nodes: sequence, mapping and scalar.


1 Answers

The spec isn't very clear, but after a bit of head-scratching I figured it out. YAML has two kinds of block mapping keys: implicit and explicit. The implicit style is the kind you're familiar with:

mapping:   foo: 1   bar baz: 2   "qux:quux": 3 

If we load this YAML in Ruby (for example) we get the following result:

{ "mapping" =>   { "foo"      => 1,     "bar baz"  => 2,     "qux:quux" => 3   } } 

But we can also use explicit style to express the same thing:

mapping:   ? foo   : 1   ? bar baz   : 2   ? "qux:quux"   : 3 

In other words, a line starting with ? indicates a key and a line starting with : indicates a value.

What use is that? Well, it lets us use any YAML structure as a mapping key. Want to use a sequence as a mapping key? You can! Want to use a mapping as a mapping key? Behold:

mapping:   # Use a sequence as a key   ? - foo     - bar   : 1    # Use a mapping as a key   ? baz: qux   : 2    # You can skip the value, which implies `null`   ? quux    # You can leave the key blank, which implies a `null` key   ?   : 3    # You can even skip both the key and value, so both will be `null`   ?    # Or you can use a preposterously long scalar as a key   ? |     We the People of the United States, in Order to form a more     perfect Union, establish Justice, insure domestic Tranquility,     provide for the common defence, promote the general Welfare,     and secure the Blessings of Liberty to ourselves and our     Posterity, do ordain and establish this Constitution for the     United States of America.   : 3    # Or just be ridiculous   ? - foo: bar       baz:       - { qux: quux }     - stahp   : 4 

In Ruby this would yield the following delightful hash:

{ "mapping" =>   { [ "foo", "bar" ]   => 1,     { "baz" => "qux" } => 2,     "quux"             => nil,     nil                => nil,     "We the People of the United States, in Order to form a more\nperfect Union, establish Justice, insure domestic Tranquility,\nprovide for the common defence, promote the general Welfare,\nand secure the Blessings of Liberty to ourselves and our\nPosterity, do ordain and establish this Constitution for the\nUnited States of America.\n" => 3     [ { "foo" => "bar", "baz" => [ { "qux" => "quux" } ] }, "stahp" ] => 4   } } 

Oh, and the "Detroit Tigers" example looks like this when Ruby parses it:

YAML.load <<YML ? - Detroit Tigers   - Chicago cubs :   - 2001-07-23  ? [ New York Yankees,     Atlanta Braves ] : [ 2001-07-02, 2001-08-12,     2001-08-14 ] YML # => { [ "Detroit Tigers", "Chicago cubs" ] => #          [ #<Date: 2001-07-23 ((2452114j,0s,0n),+0s,2299161j)> ], #      [ "New York Yankees", "Atlanta Braves" ] => #          [ #<Date: 2001-07-02 ((2452093j,0s,0n),+0s,2299161j)>, #            #<Date: 2001-08-12 ((2452134j,0s,0n),+0s,2299161j)>, #            #<Date: 2001-08-14 ((2452136j,0s,0n),+0s,2299161j)> ] #     } 
like image 86
Jordan Running Avatar answered Sep 28 '22 08:09

Jordan Running