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.arseniev ,
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!”
As always: Love, Peace and JSON
Cheers, Uwe