ABAP Code Samples : ABAP
and JSON
JSON format
is getting used widely these days. You will eventually get a requirement to to
interpret JSON data or create JSON data using SAP ABAP.
In this post, you will
lean how to do this.
1.
Validate
JSON
2.
Read
JSON
3.
Create
JSON
First, let us look at what
is JSON data. You can visit json org to learn more about JSON. Here
is a short version.
· JSON – JavaScript Object Notation
· It is a lightweight
data-interchange format
· It is easy for humans to
read and write
· It is easy for machines to
parse and generate
· It is based on a subset of
the JavaScript Programming Language Standard
· JSON is built on two
structures:
o
A
collection of name-value pairs
o
An
ordered list of values
JSON Examples
The first example has a
collection of name & value pairs. These pairs are name & Amar, age
& 18, and city & Mumbai.
{
"name": "Amar",
"age": 18,
"city": "Mumbai"
}
The second example below,
shows the list of collections from first example. Each value in the JSON can
either be direct value or list of name-value pairs / collections included in [
] and separated by comma i.e. ‘,’.
{
"students": [{
"name": "Amar",
"age": 18,
"city": "Mumbai"
},
{
"name": "Akbar",
"age": 17,
"city": "Mumbai"
},
{
"name": "Anthony",
"age": 16,
"city": "Mumbai"
}
]
}
Sites such as https://jsonlint.com/ or https://jsonformatter.org/ can
be used to validate the JSON data or format the JSON data for our testing.
JSON vs XML
JSON is vary similar to
xml as both are human readable, both are hierarchical and both are used in
various programming languages. But JSON is simpler than XML, it does not use
end tags and hence shorter, simple to read & write
Now, let us get back to how
JSON can be handled in ABAP.
Validate Jason Data in ABAP
The class used to work with
JSON in ABAP is cl_sxml_string_reader . As
JSON and XMLs are similar – same class is used for both.
Code Sample
DATA : lv_string TYPE string VALUE '
{"name": "Amar","age":18,"city": "Mumbai"} '.
DATA(lo_reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( lv_json ) ).
TRY.
lo_reader->next_node( ).
lo_reader->skip_node( ).
cl_demo_output=>display( 'JSON is valid' ).
CATCH cx_sxml_parse_error INTO DATA(lx_parse_error).
cl_demo_output=>display( lx_parse_error->get_text( ) ).
ENDTRY.
When the JSON is valid, we get
below output.
Then
try invalid JSON by changing the JSON file to get below output.
DATA : lv_string TYPE string VALUE '{"name": "Amar","age":18,"city": "Mumbai"1}'.
Read
JSON using ABAP
Reading JSON file with linear
structure may not be a practical use case, but it will help in getting
understanding of the code block.
TYPES :
BEGIN OF ty_student,
name TYPE string,
age TYPE i,
city TYPE string,
END OF ty_student.
DATA : lv_json TYPE string VALUE '{"name": "Amar","age":18,"city": "Mumbai"}',
lr_data TYPE REF TO data,
ls_student TYPE ty_student.
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_json
pretty_name = /ui2/cl_json=>pretty_mode-user
assoc_arrays = abap_true
CHANGING
data = lr_data ).
IF lr_data IS BOUND.
ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_data>).
DO 3 TIMES. "Number of fields
CASE sy-index.
WHEN 1. DATA(lv_fname) = 'NAME'.
WHEN 2. lv_fname = 'AGE'.
WHEN 3. lv_fname = 'CITY'.
ENDCASE.
ASSIGN COMPONENT sy-index OF STRUCTURE ls_student TO FIELD-SYMBOL(<lfs_field>).
ASSIGN COMPONENT lv_fname OF STRUCTURE <lfs_data> TO FIELD-SYMBOL(<lfs_ref_value>).
IF <lfs_ref_value> IS ASSIGNED AND <lfs_field> IS ASSIGNED.
lr_data = <lfs_ref_value>.
ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_actual_value>).
IF <lfs_actual_value> IS ASSIGNED.
<lfs_field> = <lfs_actual_value>.
ENDIF.
ENDIF.
ENDDO.
cl_demo_output=>display( ls_student ).
ENDIF.
When
we know that we need the data as a table – we can use internal table instead of
structure. We constantly need to move the data from data reference to field
symbols to read the values.
TYPES :
BEGIN OF ty_student,
name TYPE string,
age TYPE i,
city TYPE string,
END OF ty_student.
DATA : lv_json TYPE string,
lr_data TYPE REF TO data,
ls_student TYPE ty_student,
lt_student TYPE STANDARD TABLE OF ty_student.
FIELD-SYMBOLS : <lfs_table> TYPE ANY TABLE.
"Prepare JSON string for testing
lv_json = '{"students": [{"name": "Amar","age": 18,"city": "Mumbai"},' &&
'{"name": "Akbar","age": 17,"city": "Mumbai"},' &&
'{"name": "Anthony","age": 16,"city": "Mumbai"} ] }'.
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_json
pretty_name = /ui2/cl_json=>pretty_mode-user
assoc_arrays = abap_true
CHANGING
data = lr_data ).
IF lr_data IS BOUND.
ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_data>).
ASSIGN COMPONENT 'STUDENTS' OF STRUCTURE <lfs_data> TO FIELD-SYMBOL(<lfs_results>).
ASSIGN <lfs_results>->* TO <lfs_table>.
LOOP AT <lfs_table> ASSIGNING FIELD-SYMBOL(<lfs_row>).
DO 3 TIMES. "Number of fields
CASE sy-index.
WHEN 1. DATA(lv_fname) = 'NAME'.
WHEN 2. lv_fname = 'AGE'.
WHEN 3. lv_fname = 'CITY'.
ENDCASE.
ASSIGN COMPONENT sy-index OF STRUCTURE ls_student TO FIELD-SYMBOL(<lfs_field>).
ASSIGN <lfs_row>->* TO FIELD-SYMBOL(<lfs_row_val>).
ASSIGN COMPONENT lv_fname OF STRUCTURE <lfs_row_val> TO FIELD-SYMBOL(<lfs_ref_value>).
IF <lfs_ref_value> IS ASSIGNED AND <lfs_field> IS ASSIGNED.
ASSIGN <lfs_ref_value>->* TO FIELD-SYMBOL(<lfs_actual_value>).
IF <lfs_actual_value> IS ASSIGNED.
<lfs_field> = <lfs_actual_value>.
ENDIF.
ENDIF.
ENDDO.
APPEND ls_student TO lt_student.
ENDLOOP.
cl_demo_output=>display( lt_student ).
ENDIF.
Create JSON using ABAP
SELECT * FROM scarr INTO TABLE @DATA(lt_scarr).
DATA(lv_json) = /ui2/cl_json=>serialize(
data = lt_scarr
compress = abap_true
pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
" Display JSON in ABAP
CALL TRANSFORMATION sjson2html SOURCE XML lv_json
RESULT XML DATA(lvc_html).
cl_abap_browser=>show_html(
title = 'Sample JSON'
html_string = cl_abap_codepage=>convert_from( lvc_html ) ).
There
are more options available as well.
CALL TRANSFORMATION
In example above we used
transformation to display the json as HTML. Here, we will use it as itab to
JSON transformation.
SELECT * FROM scarr INTO TABLE @DATA(lt_scarr).
DATA(lo_writer) =
cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION id
SOURCE values = lt_scarr
RESULT XML lo_writer.
cl_abap_conv_in_ce=>create( )->convert(
EXPORTING
input = lo_writer->get_output( )
IMPORTING
data = lv_json ).
The JSON string appears like
below in debug mode.
The same json string can then be used to test the reverse
transformation.
CLEAR lt_scarr.
CALL TRANSFORMATION id
SOURCE XML lv_json
RESULT values = lt_scarr.
cl_demo_output=>display( lt_scarr ).
The
next step in this journey is to study class CL_SXML_TABLE_READER and how it can
be used to get specific data. SAP has created sample programs in package
SXML_DEMO and programs starting with DEMO_JASON_*
Source: Collected
No comments:
Post a Comment