Skip to main content

Reading JSON values

The methods of interface allows accessing attributes and converting to ABAP structure.

Examples below assume original JSON

{
"success": 1,
"error": "",
"payload": {
"text": "hello",
"num": 123,
"bool": true,
"false": false,
"null": null,
"date": "2020-07-28",
"table": [
"abc",
"def"
]
}
}

Individual value reading​

data r type ref to zif_ajson.
r = zcl_ajson=>parse( lv_json_string_from_above ).

r->is_empty( ). " returns abap_false
r->exists( '/success' ). " returns abap_true

r->get( '/success' ). " returns "1"
r->get_integer( '/success' ). " returns 1 (number)
r->get_boolean( '/success' ). " returns "X" (abap_true - because not empty)

r->get( '/payload/bool' ). " returns "true"
r->get_boolean( '/payload/bool' ). " returns "X" (abap_true)

r->get( '/payload/false' ). " returns "false"
r->get_boolean( '/payload/false' ). " returns "" (abap_false)

r->get( '/payload/null' ). " returns "null"
r->get_string( '/payload/null' ). " returns "" (empty string)

r->get( '/payload/date' ). " returns "2020-07-28"
r->get_date( '/payload/date' ). " returns "20200728" (type d)

r->members( '/' ). " returns table of "success", "error", "payload"

Segment slicing​

" Slice returns zif_ajson instance but "payload" becomes root
" Useful to process API responses with unified wrappers
data payload type ref to zif_ajson.
payload = r->slice( '/payload' ).

Performance tip: note, that slice creates a copy of the JSON tree, and so increases memory consumtion which may be an issue in some cases.

Getting node type​

In some case you might want to know node type prior to accessing it first. Type can be 'str', 'num', 'null', 'bool', 'object', 'array'.

r->get_node_type( '/payload/false' ). " returns "bool"
r->get_node_type( '/payload/text' ). " returns "str"

Converting to ABAP structure​

Instead of reading individual values, you can use to_abap for converting the JSON data into a corresponding ABAP structure. The types are mapped as follows:

JSONABAPExpected JSON format
strdate (d)"YYYY-MM-DD" or "YYYY-MM-DDT" (year, month, day, optional fixed "T")
strtime (t)"HH:MM:SS" or "HH:MM:SST" (hour, minute, seconds, optional "T")
strtimestamp (p 15,0)"YYYY-MM-DDTHH:MM:SSZ" or "YYYY-MM-DDTHH:MM:SS+XX:YY" (with timezone)
strtimestampl (p 21,7)"YYYY-MM-DDTHH:MM:SS.FFFFFFFZ" or "YYYY-MM-DDTHH:MM:SS.FFFFFFF+XX:YY" (with timezone)
strutclong"YYYY-MM-DDTHH:MM:SS.FFFFFFFZ" or "YYYY-MM-DDTHH:MM:SS.FFFFFFF+XX:YY" (with timezone)
strotherStandard ABAP value mapping
numanyStandard ABAP value mapping
boolabap_bool (c 1)true, false
null-null (ignored)
objectstructure
arraytable

Except for the special date/time mappings, JSON data will be assigned to the corresponding ABAP fields using standard ABAP data conversion rules. Look out for conversion errors which throw CX_SY_CONVERSION_ERROR or unintentionally truncating values if a target field is shorter than the value.

data:
begin of ls_payload,
text type string,
num type i,
bool type abap_bool,
false type abap_bool,
null type string,
table type string_table, " Array !
end of ls_payload.

payload->to_abap( importing ev_container = ls_payload ).

to_abap supports transferring "corresponding only" fields. This will ignore JSON attributes that do not have a matching ABAP field name (see Mapping).

payload->to_abap(
exporting iv_corresponding = abap_true
importing ev_container = ls_payload ).

" Or via an instance flag (persists after setting!)
payload->to_abap_corresponding_only( )->to_abap( importing ev_container = ls_payload ).

to_abap supports creating data references. You can determine the type of a field in the ABAP structure at runtime. For this to work, define the field as type ref to data and initialize the reference using zcl_ajson_ref_initializer_lib=>create_path_refs_init for each path to a reference field.

Example:

// 1st JSON
{ "tableName": "T002", "tableContent": { ...structure of table T002... } }
// 2nd JSON
{ "tableName": "T100", "tableContent": { ...structure of table T100... } }
data:
begin of ls_data,
table_name type string,
table_content type ref to data,
end of ls_data.

data:
ls_t002 type t002,
ls_t100 type t100,
li_refs type ref to zif_ajson_ref_initializer,
lt_refs type zif_ajson_ref_initializer=>tty_data_refs,
ls_refs like line of lt_refs.

do 2 times.
" prepare mapping of paths to data references
clear: ls_refs, lt_refs.

case sy-index.
when 1.
" 1st JSON: reference T002 structure
get reference of ls_t002 into ls_refs-dref.
when 2.
" 2nd JSON: reference T100 structure
get reference of ls_t100 into ls_refs-dref.
endcase.

ls_refs-path = '/'.
ls_refs-name = 'table_content'.
insert ls_refs into table lt_refs.

" create json instance with ref initializer
li_refs = zcl_ajson_ref_initializer_lib=>create_path_refs_init( lt_refs ).

lo_json = new zcl_ajson=>new( ii_refs_initiator = li_refs ).
lo_json->to_abap( importing ev_container = ls_data ).

" ...

enddo.