Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

convert nested JSON to ABAP

mariomueller68
Explorer
0 Kudos
578

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

8 REPLIES 8

Sandra_Rossi
Active Contributor
531

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.

 

mariomueller68
Explorer
0 Kudos
502

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

437

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

0 Kudos
408

Thank you very much!

0 Kudos
283

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.

Sandra_Rossi
Active Contributor
432

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.

 

 

0 Kudos
404

Hi Sandra,

SOLVED!!!


great work!  Thank you very much!
Greetings to italy (?)

atsybulsky
Active Participant
0 Kudos
311

As an alternative, have a look at this also: https://github.com/sbcgua/ajson