The YAML_PARSE function takes a YAML (YAML Ain't Markup Language) string or file and converts it into an IDL variable.

This routine is written in the IDL language. Its source code can be found in the file yaml_parse.pro in the lib/datatypes subdirectory of the IDL distribution.

Tip: The result of YAML_PARSE is a nested hierarchy of YAML objects, arrays, and scalar values. If you print out the result, the output will automatically be printed in YAML format.

Examples


Convert a YAML stream into a nested set of IDL YAML objects:

IDL> yaml = `MyYaml:\n key1: text1\n key2: [1, cat, 2.5]`
IDL> result = yaml_parse(yaml)
IDL> help, result
RESULT         YAML_MAP  <ID=1  NELEMENTS=1>
IDL> print, result
MyYaml:
  key1: text1
  key2:
    - 1
    - cat
    - 2.5
IDL> help, result['MyYaml']
<Expression>   YAML_MAP  <ID=2  NELEMENTS=2>
IDL> help, result['MyYaml','key2']
<Expression>   YAML_SEQUENCE  <ID=3  NELEMENTS=3>

Syntax


Result = YAML_PARSE(String, /PRESERVE_ALIAS )

Return Value


The result is a nested hierarchy of YAML objects, IDL arrays, and IDL scalar values. See below for the rules on converting YAML data into IDL datatypes.

Arguments


String

String must be a scalar string or string array containing a valid YAML stream.

String can also be a file name. In this case the entire file is read into memory and parsed as a single YAML string.

Keywords


PRESERVE_ALIAS

By default, YAML_PARSE automatically resolves all YAML aliases from their corresponding anchors and returns the resulting values, including any value overrides. If PRESERVE_ALIAS is set then the result will contain the original, unmodified aliases as YAML_Value and YAML_Alias objects. For example, here we have an anchor for a "planet" mapping. The "Earth" key is just a direct alias, while the "Jupiter" key overrides one of the mapping keys:

yaml = `
default: &planet
  type: terrestrial
Earth: *planet
Jupiter:
  <<: *planet
  type: gas giant`
print, yaml_parse(yaml) ; resolve all aliases

IDL prints:

default:
  type: terrestrial
Earth:
  type: terrestrial
Jupiter:
  type: gas giant

Now print the YAML but keep the aliases using the PRESERVE_ALIAS keyword:

print, yaml_parse(yaml, /preserve_alias)

IDL prints:

default: &planet
  type: terrestrial
Earth: *planet
Jupiter:
  <<: *planet
  type: gas giant

Conversion Rules


When converting YAML streams into IDL variables, the following rules are used:

YAML Item IDL Variable Type Notes
Multiple Documents YAML_Multidoc

Optional COMMENTS, GLOBAL_TAGS

A single document with a mapping YAML_Stream_Map

Optional COMMENTS, GLOBAL_TAGS

A single document with a sequence

YAML_Stream_Sequence

Optional COMMENTS, GLOBAL_TAGS

Mapping YAML_Map

Optional ANCHOR, TAG properties

!!set YAML_Map Mapping of keys with !NULL values
Sequence of mixed types YAML_Sequence

Optional ANCHOR, TAG properties

Sequence of same types1 Array

Boolean, LONG64, DOUBLE, DCOMPLEX

!!omap YAML_Sequence Sequence of YAML_Maps
Scalar value with unknown tag3 YAML_Value TAG and VALUE properties
Scalar value with an anchor2 YAML_Value

ANCHOR, VALUE properties, optional TAG

Alias (reference) YAML_Alias ALIAS property
Quoted string String  
~, null, Null, NULL !NULL  

false, False, FALSE, true, True, TRUE

Boolean  
Integer from –263 to 263–1 LONG64  
Integers larger than +/–263 BigInteger  
Floating-point number DOUBLE  
!!binary with base64 Byte array  

!!python/complex or complex of form A+Bj

DCOMPLEX  
tag:stsci.edu:asdf/core/complex-1.0.0 DCOMPLEX ASDF file format

1A sequence with both integers and floating-point values will be returned as an IDL array of type DOUBLE.

2A YAML scalar with an anchor will be returned as a YAML_Value object. The VALUE property will contain the scalar value as a string, and will not be converted to one of the other scalar types.

3A YAML scalar with an unknown tag will be returned as a YAML_Value object. The VALUE property will contain the scalar value as a string, and will not be converted to one of the other scalar types.

Conformance


In general, YAML_PARSE and YAML_SERIALIZE conform to the YAML 1.2 standard, with the following specific notes:

  • The presence of a %YAML 1.1 directive does not change any of the following behavior.

  • Unquoted strings On, Off, Yes, No are treated as strings (not booleans as in YAML 1.1).

  • Octal numbers must use the 0o prefix (YAML 1.1 treated an integer with a leading zero as octal).

  • Values with the form 12:34:56 are returned as strings and do not need quoting (YAML 1.1 treated them as sexigesimals).

Some exceptions to the conformance:

  • YAML Mappings are returned as a YAML_Map, which is an ordered hash, rather than unordered. This makes it easier to parse and serialize YAML files and have the mappings appear in the same order.

  • Mapping keys can only be strings or numbers. Complex mapping keys (such as maps or sequences) will produce unexpected results.

  • For parsing, Infinity or NaN values do not require a leading ".". For example, inf, infinity, or .inf will all be treated as floating-point Infinity, unless they are surrounded by quotes. YAML_SERIALIZE will always output these with the leading ".", for example .inf or .nan.

Additional Examples


Parsing a YAML File

First we parse a sample YAML file into YAML objects:

yaml = [ $
'Product: IDL', $
'Year: 1977', $
'Creator: David Stern', $
'Datatypes: [boolean, long, float, string]', $
'Examples: [true, 1234, 3.14, "hello"]', $
'Functions:', $
' - FFT:', $
'   Arguments: [{Name: InputArray, Type: float}]', $
'   Keywords: [{Name: Double, Type: boolean}]']
yp = yaml_parse(yaml)

We can use help and print to examine the contents:

help, yp
print, (yp.keys()).toArray()

IDL prints:

YP              YAML_MAP  <ID=3  NELEMENTS=6>
Product Year Creator Datatypes Examples Functions

We can use array indexing to drill down into the returned objects:

help, yp['Datatypes']
help, yp['Examples']
help, yp['Functions', 0, 'FFT', 'Arguments', 0, 'Name']

IDL prints:

<Expression>    STRING    = Array[4]
<Expression>    YAML_SEQUENCE  <ID=5  NELEMENTS=4>
<Expression>    STRING    = 'InputArray'

Convert to JSON

If the YAML file contains simple YAML_Map, YAML_Sequence, arrays, and scalars, then you can directly convert the YAML_PARSE output to JSON:

IDL> print, json_serialize(yp)
{"Product":"IDL","Year":1977,"Creator":"David Stern","Datatypes":["boolean","long","float","string"],"Examples":[true,1234,3.1400000000000001,"hello"],"Functions":[{"FFT":{"Arguments":[{"Name":"InputArray","Type":"float"}],"Keywords":[{"Name":"Double","Type":"boolean"}]}}]}

This will not work for YAML files that contain streams or special TAG values.

Create YAML Streams

You can construct YAML output from regular IDL arrays, scalars, hashes, or lists. More complex YAML files can be created using the YAML object classes such as YAML_Multidoc, YAML_Stream_Map, YAML_Stream_Sequence, YAML_Map, or YAML_Sequence. These classes allow you to add YAML comments, global tags, anchors, and tags.

For our simple example above, we can recreate the YAML by just using regular IDL variables:

h = OrderedHash()
h['Product'] = 'IDL'
h['Year'] = 1977
h['Creator'] = 'David Stern'
h['Datatypes'] = ["boolean","long","float","string"]
h['Examples'] = List(!true, 1234, 3.14d, "hello")
args = [Hash('Name', 'InputArray', 'Type', 'float')]
kw = [Hash('Name', 'Double', 'Type', 'boolean')]
fn1 = Hash('FFT', Hash('Arguments', args, 'Keywords', kw))
h['Functions'] = List(fn1)
print, yaml_serialize(h)

This will produce essentially the same YAML stream as in the beginning, although some of the YAML mappings and sequences will be written out in "block" format rather than the shorter "flow" style. Both forms are equivalent.

Version History


8.9

Introduced

See Also


YAML_Alias, YAML_Map, YAML_Sequence, YAML_Multidoc, YAML_Stream_Map, YAML_Stream_Sequence, YAML_Value, YAML_SERIALIZE