YAML_PARSE
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 |
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