The JSON_PARSE function takes a JSON (JavaScript Object Notation) 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 json_parse.pro in the lib subdirectory of the IDL distribution.
Tip: The default result of JSON_PARSE is either a LIST or an ORDEREDHASH. If you print out the result using Implied Print, then the output will automatically be printed in JSON format.
Examples
Convert JSON array into a LIST
json = '[true,null,42,3.14,"Hello"]'
result = JSON_PARSE(json)
HELP, result
result
IDL prints:
RESULT LIST <ID=3 NELEMENTS=5>
[
true,
null,
42,
3.1400000000000001,
"Hello"
]
Convert JSON object into an ORDEREDHASH
json = '{"Jupiter":{"Europa":4.8e22, "Ganymede":1.48e23}}'
result = JSON_PARSE(json)
HELP, result
result
PRINT, result['Jupiter'].Keys()
PRINT, result['Jupiter', 'Europa']
IDL prints:
RESULT HASH <ID=3 NELEMENTS=1>
{
"Jupiter":
{
"Ganymede": 1.4800000e+023,
"Europa": 4.8000000e+022
}
}
Ganymede
Europa
4.8000000e+022
Convert JSON array into an IDL array
json = '["Mercury", "Venus", "Earth"]'
result = JSON_PARSE(json, /TOARRAY)
PRINT, result
IDL prints:
Mercury
Venus
Earth
Convert an IDL structure into a JSON string and back into an IDL structure
mystruct = {TRUE: !TRUE, FALSE: !FALSE, INT: 5, FLOAT: 3.14, $
STR: "Hello", INTARRAY: [1,2,3,4,5], FLOATARRAY: [1.0,2.0,3.0]}
json = JSON_SERIALIZE(mystruct)
output = JSON_PARSE(json, /TOARRAY, /TOSTRUCT)
HELP, output
IDL prints:
** Structure <1d8ea18>, 7 tags, length=104, data length=98, refs=1:
TRUE BOOLEAN true (1)
FALSE BOOLEAN false (0)
INT LONG64 5
FLOAT DOUBLE 3.1400001
STR STRING 'Hello'
INTARRAY LONG64 Array[5]
FLOATARRAY DOUBLE Array[3]
Syntax
Result = JSON_PARSE(String, /DICTIONARY, /FOLD_CASE, /TOARRAY, /TOSTRUCT )
Return Value
If String begins with a curly brace "{", then the result is an ORDEREDHASH (or a structure if TOSTRUCT is set), containing the ordered key-value pairs from the JSON string. If String begins with a square bracket "[", then the result is a LIST (or an array if TOARRAY is set), containing the ordered collection of values.
If String is a scalar string that does not begin with "{" or "[", then it is assumed to be a file name. If the file exists, then the contents of the file are read and parsed.
When converting JSON values into IDL variables, the following rules are used:
- "null" becomes !NULL, unless the TOSTRUCT keyword is set, in which case the string "!NULL" is used.
- "false" and "true" become IDL booleans.
- An integer value in the range -263 to 263–1 becomes an IDL variable of type LONG64.
- An integer value in the range 263 to 264–1 becomes an IDL variable of type ULONG64.
- An integer value greater than or equal to 264 becomes an IDL variable of type DOUBLE (in this case some precision will be lost as doubles can only represent an exact integer up to about 253).
- A floating-point number becomes an IDL variable of type DOUBLE. JSON_PARSE will recognize the special unquoted NaN and Infinity values, and will correctly return the floating-point values for NaN and Infinity.
- A string will be converted to an IDL string. Any escaped characters (preceded by a "\") will be converted back to normal characters.
- A JSON array becomes an IDL LIST variable, unless the TOARRAY keyword is set, in which case an IDL array is returned.
- A JSON object becomes an IDL ORDEREDHASH variable, unless either the DICTIONARY or TOSTRUCT keyword is set.
Arguments
String
String must be a valid JSON string containing either a JSON object of name-value pairs, or a JSON array of values. If String is not valid JSON, JSON_PARSE will parse String until the first instance of invalid JSON.
String can also be a file name. In this case the entire file is read into memory and parsed as a single JSON string.
Keywords
DICTIONARY
If this keyword is set, then any JSON objects within the result (including the result itself) will be returned as DICTIONARY variables, instead of ORDEREDHASH variables. For IDL dictionaries, the keys are case insensitive and can be accessed using IDL's "dot" notation, similar to IDL structures. For example:
json = '{"Jupiter":{"Europa":4.8e22, "Ganymede":1.48e23}}'
result = JSON_PARSE(json, /DICTIONARY)
HELP, result
HELP, result.jupiter
PRINT, result.jupiter.Keys()
PRINT, result.jupiter.europa
IDL prints:
RESULT DICTIONARY <ID=3 NELEMENTS=1>
<Expression> DICTIONARY <ID=10 NELEMENTS=2>
Ganymede Europa
4.8000000e+022
Note: The JSON format specifies that key names are case sensitive. If you have a JSON object with two keys that are identical except for their case, then using the DICTIONARY keyword will only return the second key/value pair.
Note: To use the DICTIONARY keyword successfully, all of the JSON keys must be valid IDL variable names (no special characters or spaces). If any keys are not valid then an error is thrown.
FOLD_CASE
By default, the keys returned in the ORDEREDHASH are case sensitive. If the FOLD_CASE keyword is set, then the ORDEREDHASH variable will be case insensitive. For example:
json = '{"My Key":1.23}'
result = JSON_PARSE(json, /FOLD_CASE)
PRINT, result.Keys()
PRINT, result['MY KEY']
IDL prints:
My Key
1.2300000
This keyword is ignored when either the DICTIONARY or TOSTRUCT keyword is set.
Note: When using FOLD_CASE, the original case is preserved within the OrderedHash key list. You could therefore pass this OrderedHash back into JSON_SERIALIZE to reproduce the original JSON.
TOARRAY
If this keyword is set, then any JSON arrays within the result (including the result itself) will be returned as IDL arrays, instead of LIST variables.
Note: For this keyword to work correctly, each JSON array within the result must contain values that can all be converted to the same data type. The data type of each array will be determined by using the "highest" type within that array. For example, if your JSON array has two integer values and one decimal value, the resulting array will have type DOUBLE. For details on the rules used for type promotion, see List::ToArray under the PROMOTE_TYPE keyword.
TOSTRUCT
If this keyword is set, then any JSON objects within the result (including the result itself) will be returned as IDL structures, instead of ORDEREDHASH variables.
Note: Since IDL structure tags must be valid IDL identifiers, any spaces or special characters within the JSON keys will be converted to underscore characters. In addition, all keys will be converted to uppercase. Finally, any "null" values will be converted to the string "!NULL" since you cannot have a null field in a structure. If you need to convert the result back into an equivalent JSON string, do not use this keyword and return the result as an ORDEREDHASH instead.
Resources and References
JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write, and for machines to parse and generate. JSON was designed as an alternative to XML, and is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. Further details can be found at https://www.json.org/json-en.html.
JSON_PARSE supports a few non-standard extensions to JSON, including trailing commas on arrays and objects, as well as the special NaN, Inf, and Infinity floating-point values.
Version History
8.2 |
Introduced |
8.3 |
Added DICTIONARY keyword
Updated references from HASH to ORDEREDHASH
|
8.4 |
The TOARRAY keyword now uses all of the array elements to determine the type, not just the first element. Values for "false" and "true" now use BOOLEAN variables.
Added FOLD_CASE keyword.
|
9.1 |
Add support for trailing commas on arrays, and unquoted NaN, Inf, and Infinity values. |
See Also
JSON_SERIALIZE, HASH, ORDEREDHASH, LIST, HttpRequest