PARSE JSON

PARSE JSON operand1 [ENCODED[IN] CODEPAGE operand2]
   

INTO

Opening bracket

PATH operand3 [WITH SEPARATOR operand4] [NAME operand5] [VALUE operand6]

Closing bracket

  NAME operand5 [VALUE operand6]    
  VALUE operand6      
    [ GIVING operand7 [SUBCODE operand8]]
       statement...
END-PARSE (structured mode only)
LOOP (reporting mode only)

This document covers the following topics:

For an explanation of the symbols used in the syntax diagram, see Syntax Symbols.

Related Statement: REQUEST DOCUMENT.

Belongs to Function Group: Internet and Parsing.


PARSE JSON Usage

The PARSE JSON statement allows you to parse JSON documents from a Natural program. See also Statements for Internet Access and Parsing in the Programming Guide.

It is recommended that you use dynamic variables when using the PARSE JSON statement, because it is not feasible to determine the length of a static variable. Using static variables might result in the truncation of the value intended for the variable.

For information on Unicode support, see PARSE JSON in the Unicode and Code Page Support documentation.

Mark-Up

The markings below are used in path strings to represent the various data structures and their statuses in a JSON document:

Marking JSON Data Location in Path String
< Start of an Object At the beginning, at the end, or between field names
> End of an Object At the end
( Start of an Array At the beginning, at the end, or between field names
) End of an Array At the end
/ Separator

Note:
You can customize the separator marker using operand2

 
$ Parsed data - character data string At the end

By using this additional markup in the path string, you can differentiate the elements of the JSON document in the output more easily.

Related System Variables

The following Natural system variables are automatically created for each PARSE JSON statement that is executed:

The notation (r) after *PARSE-TYPE, *PARSE-LEVEL, and *PARSE-INDEX is used to indicate the label or statement number of the statement in which the PARSE was issued. If (r) is not specified, the corresponding system variable represents the system variable of the JSON data currently processed in the active PARSE processing loop.

For more information on these system variables, see the System Variables documentation.

PARSE JSON Syntax Description

Operand Definition Table:

Operand Possible Structure Possible Formats Referencing Permitted Dynamic Definition
operand1 C S       A U B                     yes no
operand2 C S       A                         yes no
operand3   S       A U B                     yes yes
operand4 S       A U B                     yes no
operand5   S       A U B                     yes yes
operand6   S       A U B                     yes yes
operand7   S             I4                   yes yes
operand8   S             I4                   yes yes

Syntax Element Description:

Syntax Element Description
operand1
JSON Document:
Operand1 represents the JSON document to be parsed. The JSON document might not be changed while being parsed. If you try to change the JSON document during parsing, the change does not take effect in the PARSE process.
ENCODED [IN] CODEPAGE operand2
ENCODED [IN] CODEPAGE:

Operand2 denotes the code page of the JSON document represented by operand1

PATH operand3
Path:

Operand3 represents the PATH of a data in the JSON document.

The PATH contains the NAME of the identified JSON part, the NAMEs of all parents, as well as the type of the JSON part. Every name in the PATH is separated by operand4 called Separator.

Note:
The information given with PATH can be used to easily fill a tree view.

See also Example 1 - Using the PATH Option.

SEPARATOR operand4
Separator:

Operand4 represents the Separator sign used to separate NAME and Mark-Up in the PATH (operand3). The default Separator sign used in the PATH (operand3) is a slash (/).

See also Example 2 - Using the PATH with SEPARATOR Option.

NAME operand5
Data Element Name:

Operand5 represents the NAME of a data element in the JSON document.

If NAME has no value, then the dynamic variable associated with it is set to *LENGTH()=0, which is a static variable filled with a blank.

See also Example 3 - Using the NAME Option.

VALUE operand6
Data Element Content:

Operand6 represents the content (VALUE) of a data element in the JSON document.

If there is no value, a given dynamic variable associated with it is set to *LENGTH()=0, which is a static variable filled with a blank.

See also Example 4 - Using the VALUE Option.

GIVING operand7
GIVING:

When the PARSE process encounters an error at runtime, operand7 holds the 4-digit Natural error number.

Operand7 is updated at the end of each iteration in a parse process.

GIVING applies only to error codes NAT8331. If the GIVING parameter is specified, operand7 returns 0 in the absence of an error. However, if a PARSE error occurs, operand7 returns an appropriate Natural error number.

When an error occurs and the GIVING parameter is specified, the PARSE loop is terminated and control is passed back to the statement following END-PARSE.

When GIVING is not set and an error occurs, a Natural error message is returned and program execution is suspended, unless the ON ERROR statement block is used.

See also Example 5 - Using the GIVING and SUBCODE Clauses.

SUBCODE operand8
SUBCODE:

When the PARSE process encounters an error at runtime, operand8 holds the 3-digit Reason Code associated with the error number in operand7.

Operand8 is updated at the end of each iteration in a parse process.

If SUBCODE parameter is specified, operand8 returns 0 in the absence of an error. However, if a PARSE error occurs, operand8 returns an appropriate reason code.

SUBCODE applies only to error codes NAT8331. When the SUBCODE operand is provided along with GIVING and an error occurs, the PARSE loop is terminated and control is returned to the statement following END-PARSE.

Note:
You can find the list of all reason codes for Natural error NAT8331 under JSON PARSE: Reason Codes for Error Message NAT8331

See also Example 5 - Using the GIVING and SUBCODE Clauses.

END-PARSE
End of PARSE JSON Statement:

In structured mode, the Natural reserved keyword END-PARSE must be used to end the PARSE JSON statement.

In reporting mode, the Natural statement LOOP is used to end the PARSE JSON statement.

LOOP

PARSE JSON Examples

Example 1 - Using the PATH Option

The following code:

** Example 'PAJSNEX1': PARSE JSON (with PATH and CODEPAGE)
**                                                                      
** Note: Definition of variable MYJSON needs TQMARK set to OFF.         
************************************************************************
OPTIONS TQMARK=OFF          /* Translate quotation mark                 
*
DEFINE DATA LOCAL                                                       
1 MYJSON      (A) DYNAMIC
1 MYCODEPAGE  (A) DYNAMIC                                               
1 MYPATH      (A) DYNAMIC                                               
END-DEFINE                                                              
*                                                                       
COMPRESS '{'                                                          
         '  "employee": {'                                              
         '    "@personnel-id": "30016315",'                             
         '    "full-name": {'                                           
         '      "first-name": "RICHARD",'                               
         '      "name": "FORDHAM"'                                      
         '    }'                                                        
         '  }'                                                          
         '}'                                                           
INTO MYJSON LEAVING NO                                                  
*                                                                       
MYCODEPAGE := *CODEPAGE                                                 
*                                                                       
PARSE JSON MYJSON ENCODED IN CODEPAGE MYCODEPAGE                        
                  INTO PATH MYPATH                                      
   PRINT MYPATH                                                         
END-PARSE                                                               
END

produces the following output:

<                                            
</employee                                   
</employee/<                                 
</employee/</@personnel-id                   
</employee/</@personnel-id/$                 
</employee/</full-name                       
</employee/</full-name/<                     
</employee/</full-name/</first-name          
</employee/</full-name/</first-name/$        
</employee/</full-name/</name                
</employee/</full-name/</name/$              
</employee/</full-name/>                     
</employee/>                                 
>

Example 2 - Using the PATH with SEPARATOR Option

The following code:

** Example 'PAJSNEX2': PARSE JSON (with PATH and SEPARATOR)
**                                                                      
** Note: Definition of variable MYJSON needs TQMARK set to OFF.         
************************************************************************
OPTIONS TQMARK=OFF          /* Translate quotation mark                 
*
DEFINE DATA LOCAL                                                       
1 MYJSON      (A) DYNAMIC
1 MYCODEPAGE  (A) DYNAMIC                                               
1 MYPATH      (A) DYNAMIC
1 MYSEPARATOR (A1)                                               
END-DEFINE                                                              
*                                                                       
COMPRESS '{'                                                          
         '  "employee": {'                                              
         '    "@personnel-id": "30016315",'                             
         '    "full-name": {'                                           
         '      "first-name": "RICHARD",'                               
         '      "name": "FORDHAM"'                                      
         '    }'                                                        
         '  }'                                                          
         '}'                                                           
INTO MYJSON LEAVING NO                                                  
*                                                                       
MYCODEPAGE := *CODEPAGE
MYSEPARATOR := '*'                                                  
*                                                                       
PARSE JSON MYJSON ENCODED IN CODEPAGE MYCODEPAGE                        
                  INTO PATH MYPATH WITH SEPARATOR MYSEPARATOR           
   PRINT MYPATH                                                         
END-PARSE                                                               
END

produces the following output:

<                                    
<*employee                           
<*employee*<                         
<*employee*<*@personnel-id           
<*employee*<*@personnel-id*$         
<*employee*<*full-name               
<*employee*<*full-name*<             
<*employee*<*full-name*<*first-name  
<*employee*<*full-name*<*first-name*$
<*employee*<*full-name*<*name        
<*employee*<*full-name*<*name*$      
<*employee*<*full-name*>             
<*employee*>                         
>

Example 3 - Using the NAME Option

The following code:

** Example 'PAJSNEX3': PARSE JSON (with PATH and NAME)
**                                                                      
** Note: Definition of variable MYJSON needs TQMARK set to OFF.         
************************************************************************
OPTIONS TQMARK=OFF          /* Translate quotation mark                 
*
DEFINE DATA LOCAL                                                       
1 MYJSON      (A) DYNAMIC
1 MYPATH      (A) DYNAMIC                                               
1 MYNAME      (A) DYNAMIC                                               
END-DEFINE                                                              
*                                                                       
COMPRESS '{'                                                          
         '  "employee": {'                                              
         '    "@personnel-id": "30016315",'                             
         '    "full-name": {'                                           
         '      "first-name": "RICHARD",'                               
         '      "name": "FORDHAM"'                                      
         '    }'                                                        
         '  }'                                                          
         '}'                                                           
INTO MYJSON LEAVING NO                                                  
*                                                                       
PARSE JSON MYJSON INTO PATH MYPATH NAME MYNAME                          
   DISPLAY (AL=39) MYPATH MYNAME                                        
END-PARSE                                                               
END 

produces the following output:

               MYPATH                                MYNAME
----------------------------------    -----------------------------------

<                                                                              
</employee                              employee                               
</employee/<                            employee                               
</employee/</@personnel-id              @personnel-id                          
</employee/</@personnel-id/$                                                   
</employee/</full-name                  full-name                              
</employee/</full-name/<                full-name                              
</employee/</full-name/</first-name     first-name                             
</employee/</full-name/</first-name/$                                          
</employee/</full-name/</name           name                                   
</employee/</full-name/</name/$                                                
</employee/</full-name/>                                                       
</employee/>                                                                   
>

Example 4 - Using the VALUE Option

The following code:

** Example 'PAJSNEX4': PARSE JSON (with PATH and VALUE)
**                                                                      
** Note: Definition of variable MYJSON needs TQMARK set to OFF.         
************************************************************************
OPTIONS TQMARK=OFF          /* Translate quotation mark                 
*
DEFINE DATA LOCAL                                                       
1 MYJSON      (A) DYNAMIC
1 MYPATH      (A) DYNAMIC                                               
1 MYVALUE     (A) DYNAMIC                                               
END-DEFINE                                                              
*                                                                       
COMPRESS '{'                                                          
         '  "employee": {'                                              
         '    "@personnel-id": "30016315",'                             
         '    "full-name": {'                                           
         '      "first-name": "RICHARD",'                               
         '      "name": "FORDHAM"'                                      
         '    }'                                                        
         '  }'                                                          
         '}'                                                           
INTO MYJSON LEAVING NO                                                  
*                                                                       
PARSE JSON MYJSON INTO PATH MYPATH VALUE MYVALUE                        
   DISPLAY (AL=39) MYPATH MYVALUE                                       
END-PARSE                                                               
END

produces the following output:

                MYPATH                                  MYVALUE                 
--------------------------------------- ---------------------------------------
                                                                               
<                                                                              
</employee                                                                     
</employee/<                                                                   
</employee/</@personnel-id                                                     
</employee/</@personnel-id/$            30016315                               
</employee/</full-name                                                         
</employee/</full-name/<                                                       
</employee/</full-name/</first-name                                            
</employee/</full-name/</first-name/$   RICHARD                                
</employee/</full-name/</name                                                  
</employee/</full-name/</name/$         FORDHAM                                
</employee/</full-name/>                                                       
</employee/>                                                                   
>

Example 5 - Using the GIVING and SUBCODE Clauses

The following program produces a runtime error:

** Example 'PAJSNEX5': PARSE JSON (with GIVING and SUBCODE)
**                                                                      
** Note: Definition of variable MYJSON needs TQMARK set to OFF.         
************************************************************************
OPTIONS TQMARK=OFF          /* Translate quotation mark                 
*
DEFINE DATA LOCAL                                                       
1 MYJSON      (A) DYNAMIC
1 MYPATH      (A) DYNAMIC 
1 MYNAME      (A) DYNAMIC
1 MYVALUE     (A) DYNAMIC
1 MYGIVING    (I4)      
1 MYSUBCODE   (I4)                                                      
END-DEFINE                                                              
*
* Produce Natural runtime error with incorrect JSON document
*                                                                       
COMPRESS '{'                                                          
         '  "employee": {'                                              
         '    "@personnel-id": "30016315",'                             
         '    "full-name": {'                                           
         '      "first-name": "RICHARD",'                               
         '      "FORDHAM"'     /* here the key 'name' is missing        
         '    }'                                                        
         '  }'                                                          
         '}'                                                           
INTO MYJSON LEAVING NO                                                  
*                                                                  
PARSE JSON MYJSON INTO PATH MYPATH NAME MYNAME VALUE MYVALUE
                  GIVING MYGIVING SUBCODE MYSUBCODE                     
   WRITE (AL=39) MYPATH
END-PARSE                                                               
*
IF MYGIVING NE 0                                        
  WRITE / 'Error Number:'  MYGIVING 'Subcode:' MYSUBCODE
END-IF                                                  
END

output of the given program:

<                                            
</employee                                   
</employee/<
</employee/</@personnel-id                   
</employee/</@personnel-id/$                 
</employee/</full-name                       
</employee/</full-name/<                     
</employee/</full-name/</first-name          
</employee/</full-name/</first-name/$
</employee/</full-name/</FORDHAM 
                                
Error Number:        8331 Subcode:           5

PARSE JSON: Reason Codes for Error Message NAT8331

If the JSON parsing process terminates with error messages NAT8331, the JSON input document is syntactically invalid. The reason codes returned, along with NAT8331, represent the following meanings:

Reason Codes for Error Message NAT8331
Reason Code Explanation
001 An internal error has occurred, and the PARSE process cannot proceed.
002 There is a generic syntax error.
003 VALUE is missing (or) JSON document is BLANK.
004 KEY is missing.
005 COLON is missing.
006 Either a COMMA (or) close of array/object is missing.
007 String not properly closed.
008 Invalid/unknown escape sequence (in a string).
009 Invalid UTF-8 (in a string).
010 The JSON document is empty.
211 The document root must not follow by other values.
212 Invalid escape character in string.
213 Invalid encoding in string.
214 Number too big to be stored in double.
215 Missing fraction part in number.
216 Missing exponent in number.