JSON PARSE statement

The JSON PARSE statement converts JSON text to COBOL data formats.

You can watch this video to get an overview of the JSON support in Enterprise COBOL 6.

Format

Read syntax diagramSkip visual syntax diagramJSON PARSEidentifier-1INTO identifier-2WITHDETAILIGNORINGignoring-phrase-1ALSOignoring-phrase-1INDICATINGindicating-phrase-1ALSOindicating-phrase-1ENCODINGidentifier-6literal-4FROM CODEPAGENAMEOFidentifier-3ISliteral-1OMITTEDSUPPRESSidentifier-4CONVERTINGconverting-phrase-1ALSOconverting-phrase-1ONEXCEPTIONimperative-statement-1NOTONEXCEPTIONimperative-statement-2END-JSON

ignoring-phrase-1 Format

Read syntax diagramSkip visual syntax diagramJSONNULL FOR ALLidentifier-5

indicating-phrase-1 Format

Read syntax diagramSkip visual syntax diagramidentifier-9IS JSON NULLusing-phrase-1INidentifier-10

converting-phrase-1 Format 1

Read syntax diagramSkip visual syntax diagramidentifier-7FROM JSON BOOLEANBOOL using-phrase-1
Note: indicating-phrase-1 reuses the existing using-phrase-1. See the using-phrase-1 syntax diagram below.

converting-phrase-1 Format 2

Read syntax diagramSkip visual syntax diagramidentifier-8FROM JSON NULL USINGfig-con-1

using-phrase-1 Format

Read syntax diagramSkip visual syntax diagramUSING condition-name-1condition-name-2ANDcondition-name-3literal-2ANDliteral-3
Note: To use the JSON PARSE statement, the CODEPAGE compiler option must specify a single-byte EBCDIC CCSID.
identifier-1
The data item that contains the JSON text. identifier-1 must reference one of the following items:
  • An elementary data item of category alphanumeric
  • An alphanumeric group item
  • Start of changeAn elementary data item of category national End of change
  • Start of changeA national group itemEnd of change
  • Start of changeAn elementary data item of category UTF-8End of change
  • Start of changeA UTF-8 group itemEnd of change

When identifier-1 references an alphanumeric group item, identifier-1 is treated as though it were an elementary data item of category alphanumeric. Start of changeWhen identifier-1 references a national group item, identifier-1 is processed as an elementary data item of category national. When identifier-1 references a UTF-8 group item, identifier-1 is processed as an elementary data item of category UTF-8.End of change

identifier-1 must not be defined with the JUSTIFIED clause, and cannot be a function identifier. identifier-1 can be subscripted or reference modified.

identifier-1 must not overlap identifier-2.

Start of changeidentifier-1 can be a dynamic-length elementary item of category alphanumeric or UTF-8. identifier-1 cannot be a dynamic-length group item of any category, nor an elementary item of category national.End of change

Start of changeThe JSON text is assumed to be encoded in UTF-8 (CCSID 1208) unless the ENCODING phrase is specified. End of change

All the escaped character sequences defined in the JSON specification are accepted. Also accepted is the sequence “\x”, which is generated by JSON GENERATE, and which represents the EBCDIC NL (newline) control character X'15', equivalent to the Unicode NEXT LINE control character, NX'0085'.

Conversion from Unicode of the JSON names and values is done according to the compiler CODEPAGE option in effect for the compilation.

identifier-2
The group or elementary data item to be populated from the JSON text. Start of changeidentifier-2 must reference one of the following items: End of change
  • An elementary data item of category alphanumeric
  • An alphanumeric group item
  • An elementary data item of category national
  • A national group item
  • An elementary data item of category UTF-8
  • A UTF-8 group item

identifier-2 cannot be a function identifier or be reference modified, but it can be subscripted.

identifier-2 must not overlap identifier-1.

identifier-2 and its subordinate data items must not contain the UNBOUNDED clause.

Start of changeidentifier-2 can be a dynamic-length group item or a dynamic-length elementary item of category alphanumeric or UTF-8. identifier-2 cannot be a dynamic-length group or elementary item of category national.End of change

The data description entry for identifier-2 must not contain a RENAMES clause.

The following data items that are specified by identifier-2 are ignored by the JSON PARSE statement:

  • Any subordinate unnamed elementary data items or elementary FILLER data items
  • Any slack bytes inserted for SYNCHRONIZED items
  • Any data item subordinate to identifier-2 that is defined with the REDEFINES clause or that is subordinate to such a redefining item
  • Any data item subordinate to identifier-2 that is defined with the RENAMES clause
  • Any group data item all of whose subordinate data items are ignored

All data items specified by identifier-2 that are not ignored according to the previous rules must satisfy the following conditions:

  • Each elementary data item must have a USAGE other than DISPLAY-1, FUNCTION-POINTER, INDEX, OBJECT REFERENCE, POINTER, or PROCEDURE-POINTER.
  • There must be at least one such elementary data item.
  • Each non-FILLER data-name must have a unique identifier within identifier-2.
  • If (the data declaration of) identifier-2 or any subordinate data item contains the OCCURS DEPENDING ON clause, then the object(s) of the OCCURS DEPENDING ON clause(s) must not be subordinate to identifier-2. Thus, any objects of OCCURS DEPENDING ON clauses will not be updated by the JSON PARSE statement.
Start of changeThe following example shows the UTF-8 and dynamic-length support for JSON PARSE:
01 GRP.
   05 Ac-No PIC AA9999.
   05 MORE.
      10 Stuff PIC S99V9 OCCURS 2.
   05 SSN PIC 999/99/9999.
01 UTF8DYN PIC U DYNAMIC.
   MOVE '{"GRP":{"Ac-No":"SX1234","MORE":{"Stuff":[7.8,-9.0]},"SSN":"- '987654321"}}' TO UTF8DYN.
   JSON PARSE UTF8DYN INTO GRP.
The JSON PARSE statement is used to extract and decode the JSON data within UTF8DYN and populate the following structure in GRP:
GRP:
Ac-No: SX1234
MORE:
Stuff(1): 07H (Signed Overpunch for +7.8)
Stuff(2): 09} (Signed Overpunch for -9.0)
SSN: 987/65/4321
End of change
Start of changeIGNORING phraseEnd of change
Start of changeAllows you to indicate that JSON null values shall be ignored, either for all items or the specified list of items.
Note: When JSON null values are not ignored, which is the default behavior of JSON PARSE, and null values appear within the parsed JSON text, the JSON-STATUS special register is set to 32. And, if the WITH DETAIL phrase is specified, a runtime informational message is issued.
End of change
Start of changeIf the ALL keyword is specified, JSON null values will be ignored for all items except for the following items:
  • Items that appear as identifier-8 in any specified CONVERTING phrase, in which case the JSON null values are converted to the specified value for those items.
  • Items that appear as identifier-9 in any specified INDICATING phrase, in which case the JSON null values are indicated in the respective null indicator items.
End of change
Start of changeIf identifier-5 is specified, JSON null values are ignored for that item. identifier-5 must not be simultaneously specified as neither identifier-8 nor identifier-9 and identifier-5 must be an item that references identifier-2 or is subordinate to identifier-2.End of change
Start of changeIf multiple IGNORING phrases are specified, their effects are cumulative.End of change
Start of changeINDICATING phraseEnd of change
Start of changeStart of changeAllows you to parse JSON null values for the indicated item, identifier-9, while having a value moved into an indicator item that informs you whether a JSON null value was encountered or not. The indicator item is specified either directly via identifier-10, or indirectly as the parent elementary item of condition-name-1 or condition-name-2.End of changeEnd of change
Start of changeStart of changeidentifier-10 must, and can only be specified when literal-2 and literal-3 are specified.End of changeEnd of change
Start of changeStart of changeThe indicator item must reference a single byte elementary alphanumeric data item whose data definition entry contains PICTURE X.End of changeEnd of change
Start of changeStart of changeThe values moved into the indicator item can be as follows:
  • The VALUE of condition-name-1 if a null was found or the FALSE value of condition-name-1 if a null was not found. The first VALUE clause literal will be used if multiple VALUE clause literals are specified.
  • The VALUE of condition-name-2 if a null was found and condition-name-3 if a null was not found. The first VALUE clause literal will be used if multiple VALUE clause literals are specified.
  • literal-2 if a null was found or literal-3 if a null was not found.
End of changeEnd of change
Start of changeStart of changeThe indicator item must appear within the same dimension as the indicated item.End of changeEnd of change
Start of changeStart of changeThe indicator item is otherwise ignored by the JSON PARSE statement and the JSON text in identifier-2 shall not contain name/value pairs matching any indicator item.End of changeEnd of change
Start of changeStart of changeThe indicated item must be subordinate to identifier-2.End of changeEnd of change
Start of changeStart of changecondition-name-1 must be a level-88 item specified with both the VALUE clause and the WHEN SET TO FALSE phrase.End of changeEnd of change
Start of changeStart of changecondition-name-2 and condition-name-3 must be level-88 items with the same direct parent.End of changeEnd of change
Start of changeStart of changeliteral-2 and literal-3 must be single byte alphanumeric literals.End of changeEnd of change
Start of changeThe INDICATING phrase can be specified multiple times using the ALSO keyword.End of change
Start of changeFor example, assume the item docx contains the following UTF-8 encoded text:
{ "myrecord" : { "data-1" : null } }
End of change
Start of changeConsider the following COBOL structure and statements:
  01 DOCX PIC X(1000).
  01 MY-RECORD.
    02 DATA-1-IS-NULL PIC X.
    02 DATA-1 PIC X(100).

  JSON PARSE DOCX INTO MY-RECORD
    INDICATING DATA-1 IS JSON NULL USING 'Y' AND 'N' IN DATA-1-IS-NULL
  END-JSON

  DISPLAY 'DATA-1-IS-NULL: ' DATA-1-IS-NULL
End of change
Start of changeThe output of the program would be as follows:
DATA-1-IS-NULL: Y
End of change
Start of changeStart of changeFor a summary of the ways to parse JSON null values, see Handling JSON null values.End of changeEnd of change
Start of changeENCODING phraseEnd of change
Start of changeThe ENCODING phrase specifies the encoding assumed for the source JSON document in identifier-1. The ENCODING phrase must follow these rules:
If the ENCODING phrase is omitted and:
  • If identifier-1 is alphanumeric or UTF-8, the JSON document is assumed to be encoded in Unicode UTF-8 (CCSID 1208).
  • If identifier-1 is national, the JSON document is assumed to be encoded in Unicode UTF-16 (CCSID 1200).

If the ENCODING phrase specifies a single byte EBCDIC CCSID, literal-1 of the JSON PARSE NAME phrase must be an alphanumeric literal. For more information, see Table 1. "Single byte EBCDIC coded character sets for JSON documents".

End of change
WITH DETAIL phrase

The WITH DETAIL phrase causes the JSON PARSE statement to emit runtime messages for any nonexception and exception conditions encountered during parsing.

NAME phrase

For the purpose of matching the name of a JSON name/value pair, the NAME phrase allows you to effectively change the name of a data item to the specified literal during the execution of the JSON PARSE statement.

Start of changeYou can specify OMITTED to parse an anonymous JSON object or array, whose top parent name is not specified. Start of changeFor examples of parsing JSON anonymous arrays, see Parsing JSON anonymous arrays. End of change
Notes:
  • Only anonymous JSON object or array can be parsed using OMITTED and the rest of anonymous JSON types (string, number, true, false, and null) cannot.
  • Any JSON value can be anonymous. For example, an anonymous JSON object is one whose name is omitted in a JSON name/value pair. Given the following JSON text:
    {“top” : {“A”:”value1”, “B”:”value2”}}
    “top” is a name and {“A”:”value1”, “B”:”value2”} is its JSON object value pair. When the name “top” is omitted, {“A”:”value1”, “B”:”value2”} becomes an anonymous JSON object because it does not have its corresponding name.
End of change

identifier-3 must reference identifier-2 or one of its subordinate data items. It cannot be a function identifier and cannot be reference modified or subscripted. It must not specify any data item which is ignored by the JSON PARSE statement. For more information about identifier-2, see the description of identifier-2. If identifier-3 is specified more than once in the NAME phrase, the last specification is used. If OMITTED is specified, identifier-3 must refer to identifier-2.

literal-1 must be an alphanumeric or national literal containing the JSON name to be associated with identifier-3. The literal is case-sensitive and must match the JSON name exactly.

The NAME phrase in aggregate must not result in an ambiguous name specification. For example, given the following data declarations and JSON text:
01 G.
   05 H.
      10 A pic x(10).
      10 3_ pic 9.
      10 C-C pic x(10).

'{"g": {"H": {"A": "Eh?", "3_": 5, "C-C": "See"}}}'.
Then, if it were allowed, specifying the NAME phrase as:
NAME of A is 'C-C'
would result in no data item receiving the value "Eh?", and an ambiguity about which data item should receive the value "See", effectively defining the declaration of group G as:
01 G.
   05 H.
      10 C-C pic x(10).
      10 3_ pic 9.
      10 C-C pic x(10).
which would be illegal if referenced as identifier-2 in a JSON PARSE statement. Specifying the NAME phrase as:
NAME of A is 'C-C' C-C is 'A'
is not ambiguous, and would simply swap the assignments to data items A and C-C.
Start of changeGiven the following data declaration and JSON text:
01 top1.
   02 A pic x(20).
   02 B pic x(20).

'{"A":"value1","B":"value2"}'
This anonymous JSON object can be parsed using OMITTED:
NAME top1 IS OMITTED
If OMITTED is not specified, the JSON object would need to contain a parent name called "top":
'{"top1":{"A":"value1","B":"value2"}}'
Start of changeIf literal-1 is a NATIONAL or UTF-8 literal, identifier-1 must reference a data item of category NATIONAL or UTF-8, or the ENCODING phrase must specify a CCSID of 1208 for Unicode UTF-8.End of changeEnd of change
SUPPRESS phrase

Allows you to identify and unconditionally exclude items that are subordinate to identifier-2 from assignment by the JSON PARSE statement.

identifier-4 must reference a data item that is subordinate to identifier-2 and that is not otherwise ignored by the operation of the JSON PARSE statement. identifier-4 cannot be a function identifier and cannot be reference modified or subscripted. identifier-4 can reference an entire table.

If identifier-4 specifies a group data item, that group data item and all data items that are subordinate to the group item are excluded.

Duplicate specifications of identifier-4 are permitted.

A data item that is specified in the SUPPRESS phrase, is suppressed even if the same data item is also specified in the NAME phrase.

Start of changeCONVERTING phraseEnd of change
Start of change

Allows you to specify items that will be parsed as either JSON BOOLEAN or JSON null name/value pairs.

phrase-1 Format 1
Use Format 1 to specify items that will be parsed as JSON boolean name/value pairs.

identifier-7 must be a single-byte alphanumeric elementary data item whose data definition entry contains PICTURE X.

The USING phrase provides various methods of specifying the values that shall be effectively moved into identifier-7 when a JSON BOOLEAN true or false value is encountered during parsing.

condition-name-1 must be a level-88 item directly subordinate to identifier-7 and must be specified with both the VALUE clause and the WHEN SET TO FALSE phrase. The first VALUE clause literal (of possibly many values and ranges) will be used to populate identifier-7 when parsing a JSON BOOLEAN true value. The FALSE value will be used to populate identifier-7 when parsing a JSON BOOLEAN false value.

condition-name-2 and condition-name-3 must be level-88 items directly subordinate to identifier-7 whose VALUE clauses are used to populate identifier-7 when a JSON BOOLEAN true or false value is parsed respectively. The first VALUE clause literal will be used in both cases.

literal-2 and literal-3 must be single-byte alphanumeric literals. literal-2 and literal-3 are used to populate identifier-7 when a JSON BOOLEAN true or false value is parsed respectively.

The CONVERTING phrase can be specified with multiple items to be parsed as JSON BOOLEAN name/value pairs by using the ALSO keyword.

Example: CONVERTING phrase with all three formats of the USING phrase

Consider the following COBOL structure and statements:
01 docx pic x(1000).
01 myrecord.
  02 data-a pic x.
    88 data-a-flag value ‘T’ false ‘F’.
  02 data-b pic x.
    88 data-b-true value ‘1’.
    88 data-b-false value ‘0’.
  02 data-c pic x.
JSON PARSE docx INTO myrecord
  CONVERTING data-a FROM BOOLEAN USING data-a-flag
        ALSO data-b FROM BOOLEAN USING data-b-true AND data-b-false
        ALSO data-c FROM BOOLEAN USING ‘a’ AND ‘z’
DISPLAY data-a
DISPLAY data-b
DISPLAY data-c
Assume docx contains the following UTF-8 encoded JSON text:
{ “myrecord” :
  { “data-a” : true,
    “data-b” : false,
    “data-c” : true
  }
}
The output of the program would be:
T
0
a
Start of changephrase-1 Format 2End of change
Start of changeUse Format 2 to specify items that might be parsed as JSON null name/value pairs.

identifier-8 must be a group or elementary item that references identifier-2 or is subordinate to identifier-2.

fig-con-1 represents one of the figurative constants from the list below:
  • SPACE, SPACES
  • ZERO, ZEROES, ZEROS
  • LOW-VALUE, LOW-VALUES
  • HIGH-VALUE, HIGH-VALUES

The figurative constant is moved to identifier-8 when a JSON null value is encountered for that name. fig-con-1 must be a legal sender in the implicit move with identifier-8 as the receiver according to the rules in MOVE statement.

The following example shows JSON text containing null values being parsed into a COBOL data item using the CONVERTING phrase. Assume the item docx contains the following UTF-8 encoded text:
{ "my-record" : { "data-a" : null, "data-b" : null } }
01 my-record.
  02 data-a pic 9999.
  02 data-b pic x(10).

MOVE 1234 to data-a
MOVE "0123456789" to data-b

JSON PARSE docx INTO my-record
  CONVERTING data-a FROM NULL USING ZERO
        ALSO data-b FROM NULL USING SPACES
END-JSON
DISPLAY data-a
DISPLAY "'" data-b "'"
The output of the program would be as follows:
0000
'          '
End of change
End of change
ON EXCEPTION phrase

An exception condition exists when an error occurs during parsing of the JSON text, for example an ill-formed JSON value, or during assignment of a value to a COBOL data item. In such cases, JSON parsing stops and the receiver, identifier-2, might be partially modified.

Special register JSON-CODE contains an exception code, as detailed in JSON PARSE conditions and associated codes and runtime messages in the Enterprise COBOL Programming Guide. Special register JSON-STATUS might also contain a nonzero status value, representing one or more non-exception conditions that occurred prior to the exception condition. For more details, see Operation of JSON PARSE.

If the ON EXCEPTION phrase is specified, control is transferred to imperative-statement-1. If the ON EXCEPTION phrase is not specified, the NOT ON EXCEPTION phrase, if any, is ignored, and control is transferred to the end of the JSON PARSE statement.

NOT ON EXCEPTION phrase

If an exception condition does not occur during parsing of the JSON text, control is passed to imperative-statement-2, if specified, otherwise to the end of the JSON PARSE statement. The ON EXCEPTION phrase, if specified, is ignored. Special register JSON-CODE contains zero after execution of the JSON PARSE statement.

Nonexception conditions that can occur during execution of the JSON PARSE statement might result in special register JSON-STATUS being set to a nonzero status value, and the receiver identifier-2 being partially modified.

For more details, see “Operation of JSON PARSE” and JSON PARSE conditions and associated codes and runtime messages in the Enterprise COBOL Programming Guide.

END-JSON phrase

This explicit scope terminator delimits the scope of JSON GENERATE or JSON PARSE statements. END-JSON permits a conditional JSON GENERATE or JSON PARSE statement (that is, a JSON GENERATE or JSON PARSE statement that specifies the ON EXCEPTION or NOT ON EXCEPTION phrase) to be nested in another conditional statement.

The scope of a conditional JSON GENERATE or JSON PARSE statement can be terminated by:

  • An END-JSON phrase at the same level of nesting
  • A separator period

END-JSON can also be used with a JSON GENERATE or JSON PARSE statement that does not specify either the ON EXCEPTION or the NOT ON EXCEPTION phrase.

For more information about explicit scope terminators, see Delimited scope statements.

Start of change

Examples of JSON text and JSON PARSE statements

Start of changeGiven the following COBOL data declaration:
 01 TOP1.                           
    02 A PIC X(20) OCCURS 2.        
    02 B OCCURS 2.                  
      03 C PIC 9(2).                
      03 D PIC 9(2).                
Below are examples of JSON text and its corresponding JSON PARSE statement that can parse the JSON text:
{ "TOP1" :                         
  { "A" : ["VALUE1", "VALUE2"],    
    "B" : [{"C":11, "D":22},       
           {"C":33, "D":44}]    }} 

JSON PARSE JSON-TEXT INTO TOP1
{ "A" : ["VALUE1", "VALUE2"],    
  "B" : [{"C":11, "D":22},       
         {"C":33, "D":44}]    }} 

JSON PARSE JSON-TEXT INTO TOP1
  NAME TOP1 IS OMITTED
{ "A" : ["VALUE1", "VALUE2"] }

JSON PARSE  JSON-TEXT INTO A 
["VALUE1", "VALUE2"]

 JSON PARSE  JSON-TEXT INTO A               
   NAME A IS OMITTED    
{ "B" : [{"C":11, "D":22},   
         {"C":33, "D":44}] } 

JSON PARSE JSON-TEXT INTO B 
[{"C":11, "D":22}, 
 {"C":33, "D":44}] 

JSON PARSE JSON-TEXT INTO B              
  NAME B IS OMITTED   
End of change
End of change

Video resource

Watch the following video to get an overview of the JSON support in Enterprise COBOL 6.

Watch full-screen video on IBM® MediaCenter