Since my JSON parsing class zJSON is celebrating its 10th anniversary this year and its “successor” /ui2/cl_json – in combination with /ui2/cl_data_access – now has (nearly) all the needed functions built in, it’s time to retire (the class of course, not me unfortunately).
To make the farewell easier for us all, I’ve created a little “How To Migrate”, where I’ll compare the examples of the zJSON Wiki ( se38/zJSON Wiki · GitHub ) with the new solution.
Usage (Release 0.2.x)
Creating a JSON document with ABAP data (you can pass any structure/table/complex data, except objects)
zJSON |
/ui2/cl_json |
SELECT * FROM scarr
INTO TABLE @DATA(scarr_t)
UP TO 3 ROWS.
DATA(json) = zcl_json_document=>create_with_data( scarr_t
)->get_json( ).
|
SELECT * FROM scarr
INTO TABLE @DATA(scarr_t)
UP TO 3 ROWS.
DATA(json) = /ui2/cl_json=>serialize( scarr_t ).
|
Result
[
{
"mandt" :"001",
"carrid" :"AA",
"carrname" :"American Airlines",
"currcode" :"USD",
"url" :"http://www.aa.com"
},
{
"mandt" :"001",
"carrid" :"AB",
"carrname" :"Air Berlin",
"currcode" :"EUR",
"url" :"http://www.airberlin.de"
},
{
"mandt" :"001",
"carrid" :"AC",
"carrname" :"Air Canada",
"currcode" :"CAD",
"url" :"http://www.aircanada.ca"
}
]
|
New in version 0.2.1
Append multiple data objects
zJSON |
/ui2/cl_json |
SELECT SINGLE * FROM mara
INTO @DATA(mara_data)
WHERE matnr = '100-100'.
SELECT * FROM marc
INTO TABLE @DATA(marc_data_t)
WHERE matnr = '100-100'.
DATA(json_doc) = zcl_json_document=>create( ).
json_doc->append_data( data = mara_data iv_name = 'MARA' ).
json_doc->append_data( data = marc_data_t iv_name = 'MARC' ).
DATA(json) = json_doc->get_json( ).
|
Not (yet) implemented directly (?)Workaround:
TYPES t_marc TYPE STANDARD TABLE OF marc WITH EMPTY KEY.
DATA: BEGIN OF material,
mara TYPE mara,
marc TYPE t_marc,
END OF material.
SELECT SINGLE * FROM mara
INTO @material-mara
WHERE matnr = '100-100'.
SELECT * FROM marc
INTO TABLE @material-marc
WHERE matnr = '100-100'.
DATA(json) = /ui2/cl_json=>serialize( material ).
|
Result
{
"MARA":
{
"mandt" :"800",
"matnr" :"100-100",
"ersda" :"19941107",
"ernam" :"BALLER",
..
"fiber_part5" :"000",
"fashgrd" :""
},
"MARC":
[
{
"mandt" :"800",
"matnr" :"100-100",
"werks" :"1000",
"pstat" :"VEDPALSQGF",
..
"ref_schema" :"",
"min_troc" :"000",
"max_troc" :"000",
"target_stock" :0.000
}
]
}
|
New in version 0.2.3
Get ABAP data object from JSON string:
Assume our JSON contains the following data (a structure object and a table)
{
"scarr" :
{"mandt" :"001",
"carrid" :"LH",
"carrname" :"Lufthansa",
"currcode" :"EUR",
"url" :"http://www.lufthansa.com"
},
"sflight" :
[{"mandt" :"001",
"carrid" :"LH",
"connid" :"0400",
"fldate" :"20100821",
..
"seatsocc_f" :10},
{"mandt" :"001",
"carrid" :"LH",
"connid" :"0400",
"fldate" :"20100918",
..
"seatsocc_f" :10}
]
}
DATA: BEGIN OF flight_data,
scarr TYPE scarr,
sflight TYPE flighttab,
END OF flight_data.
zJSON |
/ui2/cl_json |
zcl_json_document=>create_with_json( json
)->get_data( IMPORTING data = flight_data ).
|
/ui2/cl_json=>deserialize(
EXPORTING
json = json
CHANGING
data = flight_data
).
|
New in version 0.2.6
Formatted output of a JSON string (for test purposes)
zJSON |
/ui2/cl_json |
zcl_json_document=>create_with_data( flight_data
)->dumps( IMPORTING result = DATA(result) ).
LOOP AT result REFERENCE INTO data(line).
WRITE:/ line->*.
ENDLOOP.
|
Not (yet) implemented directly (?)Workaround:
DATA(json) = /ui2/cl_json=>serialize( flight_data ).
cl_demo_output=>display_json( json ).
|
Result
{
"itab" :
[
{
"mandt" : 001,
"carrid" : "AA",
"carrname" : "American Airlines",
"currcode" : "USD",
"url" : "http://www.aa.com"
},
{
"mandt" : 001,
"carrid" : "AB",
"carrname" : "Air Berlin",
"currcode" : "EUR",
"url" : "http://www.airberlin.de"
},
{
"mandt" : 001,
"carrid" : "AC",
"carrname" : "Air Canada",
"currcode" : "CAD",
"url" : "http://www.aircanada.ca"
}
]
}
|
Working with nested arrays/tables (new in version 0.2.10)
Please note: the JSON document class is only able to keep one array and one JSON data string in memory. If you have to parse a nested array, you need one JSON class instance per nested array.
DATA(json) = `[[123,"abc"],[456,"def","another one"]]`.
zJSON |
/ui2/cl_json |
DATA(json_doc) = zcl_json_document=>create_with_json( json = json ).
WHILE json_doc->get_next( ) IS NOT INITIAL.
DATA(json_doc2) = zcl_json_document=>create_with_json(
json = json_doc->get_json( ) ).
WHILE json_doc2->get_next( ) IS NOT INITIAL.
json = json_doc2->get_json( ).
WRITE:/ json.
ENDWHILE.
ENDWHILE.
|
DATA target TYPE REF TO data.
/ui2/cl_json=>deserialize(
EXPORTING json = json
CHANGING data = target ).
FIELD-SYMBOLS <table1> TYPE ANY TABLE.
FIELD-SYMBOLS <line1> TYPE any.
FIELD-SYMBOLS <table2> TYPE ANY TABLE.
FIELD-SYMBOLS <line2> TYPE any.
FIELD-SYMBOLS <field> TYPE any.
ASSIGN target->* TO <table1>.
LOOP AT <table1> ASSIGNING <line1>.
ASSIGN <line1>->* TO <table2>.
LOOP AT <table2> ASSIGNING <line2>.
ASSIGN <line2>->* TO <field>.
WRITE:/ <field>.
ENDLOOP.
ENDLOOP.
|
Result
123
abc
456
def
another one
|
New in release 0.2.13
Creating a JSON document with JSON data and read content (array in this case)
DATA(json) = `[{"carrid":"LH", "carrname":"Lufthansa"},{"carrid":"UA", "carrname":"United"}]`.
zJSON |
/ui2/cl_json |
DATA(json_doc) = zcl_json_document=>create_with_json( json ).
WHILE json_doc->get_next( ) IS NOT INITIAL.
DATA(carrid) = json_doc->get_value( 'carrid' ).
DATA(carrname) = json_doc->get_value( 'carrname' ).
WRITE:/ carrid, carrname.
ENDWHILE.
|
DATA target TYPE REF TO data.
/ui2/cl_json=>deserialize(
EXPORTING json = json
CHANGING data = target ).
FIELD-SYMBOLS <table> TYPE ANY TABLE.
FIELD-SYMBOLS <line> TYPE any.
ASSIGN target->* TO <table>.
LOOP AT <table> ASSIGNING <line>.
DATA(data_access) = /ui2/cl_data_access=>create( ir_data = <line> ).
DATA carrid TYPE string.
DATA carrname TYPE string.
data_access->at( 'carrid' )->value( IMPORTING ev_data = carrid ).
data_access->at( 'carrname' )->value( IMPORTING ev_data = carrname ).
WRITE:/ carrid, carrname.
ENDLOOP.
|
Result
LH Lufthansa
UA United
|
New option: replace underscores in fieldnames with hyphen (new in Release 2.32)
DATA: BEGIN OF struc,
field_number1 TYPE string,
field_number2 TYPE string,
END OF struc.
zJSON |
/ui2/cl_json |
DATA(json) = zcl_json_document=>create_with_data(
data = struc
replace_underscore = abap_true )->get_json( ).
|
not (yet) implemented |
Result
{
"field-number1" :"",
"field-number2" :""
}
|
New option: replace double underscores in fieldnames with CamelCase (new in Release 2.33) and vice versa
zJSON |
/ui2/cl_json |
DATA: BEGIN OF struc1,
field__two TYPE string,
__field__three TYPE string,
END OF struc1.
struc1 = VALUE #( field__two = '2' __field__three = '3' ).
DATA(json) = zcl_json_document=>create_with_data(
data = struc1
replace_double_underscore = abap_true )->get_json( ).
|
not (yet) implemented |
Result
{
"fieldTwo" :"2",
"FieldThree" :"3"
}
|
not implemented |
DATA: BEGIN OF struc2,
field_two TYPE string,
field_three TYPE string,
END OF struc2.
/ui2/cl_json=>deserialize(
EXPORTING json = json
pretty_name = /ui2/cl_json=>pretty_mode-camel_case
CHANGING data = struc2 ).
|
Mapping fieldnames between ABAP and JSON (new in Release 2.34)
ABAP field names are case insensitive
DATA: BEGIN OF struc,
field_number1 TYPE string VALUE '111',
field_number2 TYPE string VALUE '222',
field_number3 TYPE string VALUE '333',
END OF struc.
zJSON |
/ui2/cl_json |
DATA(json) = zcl_json_document=>create_with_data(
data = struc
name_mappings = VALUE #(
(
abap_name = 'field_number2'
json_name = 'ThisIsATheJSONFieldName'
)
(
abap_name = 'field_number3'
json_name = 'FieldNameThree'
)
)
)->get_json( ).
|
DATA(json) = /ui2/cl_json=>serialize(
data = struc
name_mappings = VALUE #(
(
abap = 'field_number2'
json = 'ThisIsATheJSONFieldName'
)
(
abap = 'field_number3'
json = 'FieldNameThree'
)
)
).
|
Result
{
"field_number1":"111",
"ThisIsATheJSONFieldName":"222",
"FieldNameThree":"333"
}
|
DATA(json_doc) = zcl_json_document=>create_with_json(
json = json
name_mappings = VALUE #(
(
abap_name = 'FIELD_NUMBER2'
json_name = 'ThisIsATheJSONFieldName'
)
(
abap_name = 'field_number3'
json_name = 'FieldNameThree'
)
)
).
TRY.
json_doc->get_data( IMPORTING data = struc ).
CATCH zcx_json_document.
ENDTRY.
|
/ui2/cl_json=>deserialize(
EXPORTING
json = json
name_mappings = VALUE #(
(
abap = 'field_number2'
json = 'ThisIsATheJSONFieldName'
)
(
abap = 'field_number3'
json = 'FieldNameThree'
)
)
CHANGING
data = struc
).
|
Result
STRUC
FIELD_NUMBER1 FIELD_NUMBER2 FIELD_NUMBER3
111 222 333
|
Thank you Alexey Arsenyev , Sebastian Wolf and your teams for this class and your help. May the class get the new namespace soon, maybe in the next few weeks during the “SAP Developer Code Challenge – Open Source ABAP!” 😊