3 weeks ago
Hi all,
I have a JSON like:
lv_json =
'{"meta_data": { "version": 1, "created": 1736776103233},"series": [ [1627855200000,8994.75 ], [1627858800000,8994.75 ] ]}'.
I created Types of:
TYPES: BEGIN OF ty_meta_data,
version(1) ,
created TYPE string.
TYPES: END OF ty_meta_data.
TYPES: BEGIN OF ty_single_serie,
timestamp TYPE string,
value TYPE string.
TYPES: END OF ty_single_serie.
TYPES: tty_series TYPE TABLE OF ty_single_serie.
TYPES: BEGIN OF ty_tageswerte,
meta_data TYPE ty_meta_data.
TYPES: series TYPE ty_single_serie.
TYPES: END OF ty_tageswerte.
DATA ls_tageswerte TYPE ty_tageswerte.
As you can see in line 15 there must be the error --> as series is an array in the JSON
Can anybody tell me how to modify line 15 to convert the JSON array into an ABAP-Table?
The actual code (wrong ) is:
TYPES: BEGIN OF ty_meta_data,
version(1) ,
created TYPE string.
TYPES: END OF ty_meta_data.
TYPES: BEGIN OF ty_single_serie,
timestamp TYPE string,
value TYPE string.
TYPES: END OF ty_single_serie.
TYPES: tty_series TYPE TABLE OF ty_single_serie.
TYPES: BEGIN OF ty_tageswerte,
meta_data TYPE ty_meta_data.
types: series TYPE tty_series.
TYPES: END OF ty_tageswerte.
DATA ls_tageswerte TYPE ty_tageswerte.
BREAK wkiv1302. "#EC NOBREAK
DATA: test_tageswerte_ddic TYPE /kibf/wus_bnetza_tageswerte.
lv_json =
'{"meta_data": { "version": 1, "created": 1736776103233},"series": [ [1627855200000,8994.75 ], [1627858800000,8994.75 ] ]}'.
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_json
CHANGING
* data = test_tageswerte_ddic
data = ls_tageswerte
).
thanks regards,
Mario
3 weeks ago
The question is not specific to JSON, the syntax error is about TYPES only. When used as components, you must NOT refer to Generic types, instead you must use Complete types (complete table category + complete key) see the rules in the ABAP documentation), for instance:
TYPES tty_series TYPE STANDARD TABLE OF ty_single_serie WITH EMPTY KEY.
3 weeks ago
Hi Sandra,
thank you very much. That helped. But when running the deseriliazation the internal Table in the structure
ls_tageswerte is not filled.
Here is my adopted Code:
TYPES: BEGIN OF ty_meta_data,
version(1) ,
created TYPE string.
TYPES: END OF ty_meta_data.
TYPES: BEGIN OF ty_single_serie,
timestamp TYPE string,
value TYPE string.
TYPES: END OF ty_single_serie.
TYPES tty_series TYPE STANDARD TABLE OF ty_single_serie WITH EMPTY KEY.
TYPES: BEGIN OF ty_tageswerte,
meta_data TYPE ty_meta_data,
series TYPE tty_series.
TYPES: END OF ty_tageswerte.
DATA ls_tageswerte TYPE ty_tageswerte.
DATA: test_tageswerte_ddic TYPE /kibf/wus_bnetza_tageswerte.
lv_json =
'{"meta_data": { "version": 1, "created": 1736776103233},"series": [ [1627855200000,8994.75 ], [1627858800000,8994.75 ] ]}'.
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_json
CHANGING
* data = test_tageswerte_ddic
data = ls_tageswerte
).
thanks regards,
Mario
3 weeks ago
Hi,
--------------------------------
You're on the right track, and you're absolutely correct that the issue lies with how you're defining series in ty_tageswerte.
The series field in your JSON is an array of arrays, like this:
"series": [ [1627855200000, 8994.75], [1627858800000, 8994.75] ]
So, in ABAP, you should:
Define ty_single_serie as a structure representing a single array item ([timestamp, value])
Define tty_series as a table of these structures
And then declare series in ty_tageswerte as TYPE tty_series
But also, since the JSON contains numeric values, you'll want to use DEC and INT8/STRING types instead of fixed-length strings.
Here's the corrected and functional version of your code:
✅ Correct ABAP Code:
TYPES: BEGIN OF ty_meta_data,
version TYPE i,
created TYPE string,
END OF ty_meta_data.
TYPES: BEGIN OF ty_single_serie,
timestamp TYPE string,
value TYPE string,
END OF ty_single_serie.
TYPES: tty_series TYPE STANDARD TABLE OF ty_single_serie WITH EMPTY KEY.
TYPES: BEGIN OF ty_tageswerte,
meta_data TYPE ty_meta_data,
series TYPE tty_series,
END OF ty_tageswerte.
DATA: lv_json TYPE string,
ls_tageswerte TYPE ty_tageswerte.
lv_json = `{"meta_data": { "version": 1, "created": 1736776103233},"series": [ [1627855200000,8994.75 ], [1627858800000,8994.75 ] ]}`.
CALL METHOD /ui2/cl_json=>deserialize
EXPORTING
json = lv_json
CHANGING
data = ls_tageswerte.
BREAK-POINT.
--------------------------------------------------------------------------------------------------------
🧠 Important Notes:
You can change timestamp to INT8 and value to DEC if you want proper numeric types instead of strings.
The JSON array [timestamp, value] is automatically mapped by /ui2/cl_json=>deserialize as a structure, as long as it’s defined with two fields.
/ui2/cl_json maps arrays of arrays into tables of structures if the inner arrays have a consistent length.
---------------------------------
Thanks
Kushal_Sambhunath_Banerjee
3 weeks ago
3 weeks ago
The code has no important change, it doesn't solve, the comments are not relevant for ABAP ("DEC").
You must indicate "GenAI was used to help generate this content" as per the Rules Of Engagement (https://pages.community.sap.com/resources/rules-of-engagement😞
"If you want to publish content that was helped/created by GenAI, you must add the user tag GenAI Assisted Content. For content where it's not possible to add a user tag (e.g., answers), you must include this statement: "GenAI was used to help generate this content.""
Moderator alerted to add the GenAI statement.
3 weeks ago
So, you're saying that "meta_data" is correctly deserialized, but "series" remains empty.
The JSON object "series" is an array of arrays (two square brackets) hence you need to define the same in ABAP ("table of table of" but you have to say "tty_table_1 type table of tty_table_2" and "tty_table_2 type table of ...").
This works (Ctrl+Shift+F10 to run this ABAP Unit test):
CLASS ltc_app DEFINITION FINAL
FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PRIVATE SECTION.
METHODS first_test FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_app IMPLEMENTATION.
METHOD first_test.
TYPES: BEGIN OF ty_meta_data,
version TYPE c LENGTH 1,
created TYPE string.
TYPES: END OF ty_meta_data.
* TYPES: BEGIN OF ty_single_serie,
* timestamp TYPE string,
* value TYPE string.
* TYPES: END OF ty_single_serie.
* TYPES tty_series TYPE STANDARD TABLE OF ty_single_serie WITH EMPTY KEY.
TYPES tty_single_series TYPE STANDARD TABLE OF decfloat16 WITH EMPTY KEY.
TYPES tty_series TYPE STANDARD TABLE OF tty_single_series WITH EMPTY KEY.
TYPES: BEGIN OF ty_tageswerte,
meta_data TYPE ty_meta_data,
series TYPE tty_series.
TYPES: END OF ty_tageswerte.
DATA ls_tageswerte TYPE ty_tageswerte.
DATA(lv_json) = `{"meta_data": { "version": 1, "created": 1736776103233},`
&& `"series": [ [1627855200000,8994.75 ], [1627858800000,8994.75 ] ]}`.
/ui2/cl_json=>deserialize( EXPORTING json = lv_json
CHANGING data = ls_tageswerte ).
cl_abap_unit_assert=>assert_equals(
act = ls_tageswerte
exp = VALUE ty_tageswerte( meta_data = VALUE #( version = '1'
created = '1736776103233' )
series = VALUE #( ( VALUE #( ( CONV #( 1627855200000 ) )
( CONV #( '8994.75' ) ) ) )
( VALUE #( ( CONV #( 1627858800000 ) )
( CONV #( '8994.75' ) ) ) ) ) ) ).
* series = VALUE #( ( timestamp = '1627855200000'
* value = '8994.75' )
* ( timestamp = '1627858800000'
* value = '8994.75' ) ) ) ).
ENDMETHOD.
ENDCLASS.
3 weeks ago
Hi Sandra,
SOLVED!!!
great work! Thank you very much!
Greetings to italy (?)
3 weeks ago
As an alternative, have a look at this also: https://github.com/sbcgua/ajson