ParseJSON
| Release: |
• 4.6 • 5.0 • 5.1 • 5.2 • 5.3 • 5.4 • • 6.0 • 6.1 • 6.2 • 6.3 • 6.4 • 6.5 • 6.6 • 7.0 • 7.1 |
|---|
New to Analytica 5.0
ParseJSON( json, schema, flags )
Parses «json» text into Analytica data structures without using a schema. Usually, you will obtain the «json» text from a call to ReadFromUrl (a web-service call) or ReadTextFile.
JavaScript Object Notation (JSON) is a widely used lightweight data-interchange format. It is easy for humans and machines to read and write. Nowadays it is a standard in nearly every modern webservice.
The Analytica data structures for the result, as well as the structure of the «schema», have changed in 7.0 to be much easier to use. If you load a model from an earlier release, a legacy parameter is added,
ParseJSON( json, Legacy: True )
which forces the older behavior for backward compatibility. To see that behavior, select 6.6 or earlier on the release bar at the top of this page.
Parameters
- «json»: A JSON-formatted text to parse.
- «schema»: (Optional) The identifier of a Struct object. If omitted, defaults to
_JSON. - «flags»: (optional) A bit field of flags that control various aspects of parsing. Bit settings are
- 1 = During schema-free parsing, create local indexes
.Dim1,.Dim2, ... for arrays. Without this, each level of an array is returned as a reference to a list.
- 1 = During schema-free parsing, create local indexes
The following parameters are deprecated, but will show up when a legacy model that uses ParseJSON is loaded into Analytica 7.0 or later (to preserve backward compatibility).
- «legacy»: (optional) Set to True to use the older, pre-7.0 data structures and «objectSchema».
- «objectSchema»: (optional) Used only for legacy models. Hidden parameter, but you might see it in a legacy model.
Model with these examples
The examples that appear on this page are in this example model:
- Download: ParseJSON examples on docs.ana
Parsing without a schema
The top-level item in a JSON text document should be a JSON object, for example:
Variable json1
Definition:
'{ "title" : "1984",
"author" : "George Orwell",
"year" : 1949,
"pages" : 336,
"paperback" : true
}'
Here is the result of parsing that JSON text without providing a schema:
ParseJSON(json1)→
This depicts an instance of the built-in Struct named _JSON. Double click on the «_JSON» cell to see its internals.
These members contain the data. If you save the result of ParseJSON(json1) in a variable named json1_parse1, you can access the values using, e.g.,
json1_parse1 -> author
which returns "George Orwell".
JSON with nested objects and no schema
With a JSON document containing nested objects, it creates local indexes at each level. To prevent the indexes from combining into a rectangular array, it places each member object in a reference.
Variable json2
Definition:
'{ "title" : "1984",
"author" : { "first" : "George", "last" : "Orwell" },
"year" : 1949,
"pages" : 336,
"paperback" : true
}'
- Variable parse2 :=
ParseJSON(json2) parse2→ (after clicking into the top «_JSON»):
and after double clicking the «_JSON» on 'author:
In other expression, you can now access the author's last name as
parse2->author->last
Reading JSON arrays
With no schema, ParseJSON does not map array data to existing indexes that you might have. There are two ways to read that depending on whether you set the «flags» parameter. By default, if you don't specify «flags», it returns arrays as lists and any nested array data to references to lists (to avoid having the implicit dimensions combine with other indexes).
Variable json3 :='{ "data": [ [ 1,2], [3,4], [5,6] ] }'Variable parse3 :=ParseJSON(json3)(after drilling down by double-clicking the «_JSON»):
The [...] indicates that the data member holds a list. Next, double click on the [...] to drill down further so see the contents of the list.
Each nested list becomes a reference to a list. This preserves the list structure of the JSON. The reference is necessary because Analytica doesn't allow lists of lists -- this would result in a multi-D array with more than one unnamed dimension. Drilling down into the second «ref» we see the list contents.
If you set used «flags» to 1, ParseJSON creates local indexes, named .Dim1, .Dim2, etc., for each nesting level in «json», and produces a multi-dimensional array without nesting.
Variable parse3b := ParseJSON(json3, flags:1)
Parsing with a schema
A schema describes the data structure of a Java Script object, and the Structs and indexes in your model you want to map to.
JSON object schemas
The acceptable JSON structure and final representation is described by a Struct. The Parameter declarations determine which fields are allow, which data types are allowed in each field, how JSON lists map onto existing indexes, and which Structs are used for nested JSON objects. For example, consider this json2 data again:
'{ "title" : "1984",
"author" : { "first" : "George", "last" : "Orwell" },
"year" : 1949,
"pages" : 336,
"paperback" : true
}'
This JavaScript has a top-level object (Book) and a nested object (PersonName). We could use the following Struct to encode the schema:
Struct Book( title: text atom;
author: Person atom ;
year, pages: Number atom ;
paperback : Boolean atom
)
Struct Person( first, last : Text atom )
- Variable parse4 ::=
ParseJSON( json2, Book )→
The result is now an instance of the Book struct instead of the generic _JSON struct. Double-click on «Book» to view the internals.
The author field is now an instance of the Person struct. After double-clicking on «_Person»,
You can access the field values as, for example,
parse4->author->first
Member qualifiers in schema
Each parameter of a Struct may specify a data type or a dimensionality or (or neither or both).
Data types
The data types corresponding to JSON data types are:
BooleanNumberText- The name of a Struct.
orNull-- this can be combined with any of the above.
When a data type is specified, an error issue when the data provided by the JSON is inconsistent with the declared type. If no data type is specified, then any data type is accepted for that field. In this case, there is no schema for that field, so any JSON objects that appear will produce an instance of the _JSON struct.
Array dimensions
A parameter can declare a dimensionality, which may include any of the following:
Atom[ ]-- this is synonymous withAtom[ I, J, K ]-- one or more indexes in bracketsList-- must be 1-DList of «type»-- Specifies the schema and type for list items
If you omit any dimensionality declaration, then it accepts a non-list (consistent with any data type specified) or a list or nested list, with the elements consistent with any specified data type. If the JSON has a list at that point, it returns a list, with a nested list returned as a reference to a list. If you specify flags:1 then instead of using lists of references to lists, nested lists will be returned as a multi-D array using local indexes named .Dim1, .Dim2, etc.
You can have it create a local index with a specified name and with the required length by using an index parameter in your Struct schema. The index parameter doesn't appear in your JSON, but it will appear as a member of your resulting struct by default (the value is a handle to the index), or you can qualify the index parameter with nonMember to omit it as a member of the struct.
Struct Club_with_members( members : Person[ Member_ID ] ; Member_Id : Index )
Variable json4 ::=
Definition:
'{ "members" :
[
{ "first":"Lonnie", "last":"Chrisman"},
{ "first":"Peter", "last":"Moore"},
{ "first":"Max", "last":"Henrion"}
]
}'
- Variable parse_to_Club ::=
ParseJSON( json4, Club_with_members )→ 


Excess parameters
You can tag a parameter with the Optional keyword to accept a JSON object that is missing a specific field. But if this is all you do, it will still reject JSON objects that have names not mentioned at all in the Struct's parameters.
If you want to accept fields that are not listed explicitly in your Struct's parameters, you can use an excess parameter. For example, our earlier person example could be made to accept any additional fields for the person by declaring is:
Struct Person( first, last : Text atom ; ... )
The ... parameter catches any fields other than first and last that appear. Notice that the ellipsis here is the name of the last parameter (not to be confused as the ellipsis qualifier that is used to the right of the colon to declare a parameter to be a repeated parameter.
If you want to tolerate them without an error, but not make them members of the result, use
Struct Person( first, last : Text atom ; ... : nonMember )
You can also restrict any excess fields that appear to have a specific data type or dimensionality. For example, to allow only atomic (non-list) field, you could use
Struct Person( first, last : Text atom ; ... : atom )
History
- The ParseJSON function was introduced into the Analytica Enterprise edition in Analytica 5.0.
- Made available to the Free and Professional editions in Analytica 6.6.
- Changed in Analytica 7.0 to parse JSON objects to Structs, and to use the Struct's declaration as the schema. This turned out to be dramatically easier to understand and work with than the legacy schema, so the legacy schema was deprecated.
See Also
- ParseJSON examples on docs.ana -- Analytica model with the examples of ParseJSON that appear this page.
- MakeJSON
- ReadTextFile, ReadFromUrl
- ParseCSV
- Parsing XML











Enable comment auto-refresher