Skip to Content

Archived discussions are read-only. Learn more about SAP Q&A

Transforming ABAP internal table to JSON array (rather than object)

Is there an easy way to do this using the standard CALL TRANSFORMATION?  Here's what I'm doing:

"ABAP to JSON

   writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

   CALL TRANSFORMATION id SOURCE ARRAY = lt_table

                          RESULT XML writer.

   lv_json = writer->get_output( ).

Now this generates JSON with an object named ARRAY in the proper format with sub-objects... but I don't want an object named ARRAY, I just want an unnamed array.

I searched through the documentation, the asJSON documentation seems to imply this should be possible, but doesn't specify any way to accomplish such a thing.  Leaving the name blank just generates an error.

Tried a few transformation OPTIONS as well, but none of them seem to accomplish this.

It's not a huge deal to use an object instead (although we're trying to squeeze every microsecond of performance out of this call), or even to just write my own darn transformation, but I guess I'm surprised SAP doesn't seem to support this functionality with CALL TRANSFORMATION.  Am I missing something?  Please tell me I'm missing something

Former Member
Former Member replied

I honestly can't remember why I asked this question (I think I was just confused about why the object needed a name but that turned out to not really be a problem), but here's what I ended up doing, in case it's helpful:

EDIT: I noticed above someone asked about uppercasing the JSON -- I also had to do this because the REST service I was calling required it.  You can see below I actually convert back to string to do this, though there may be a more elegant solution.

*for call to cl_http_client=>create_by_destination

   constantslc_dest    TYPE rfcdest  value 'MILEMAKER'.

*local structures for handling input/output

   DATA: ls_postal_dist type ZST_POSTAL_DIST,

         ls_postal_conv type ZST_POSTAL_DIST,

         lt_postal_conv type ZTT_POSTAL_DIST,

*for call to cl_http_client=>create_by_destination

         lo_CLIENT type ref to IF_HTTP_CLIENT,

         ls_RANDMCNALLY_JSON type ZST_RANDMCNALLY_JSON,

         lt_RANDMCNALLY_JSON type table of ZST_RANDMCNALLY_JSON,

         lv_HTTP_REASON type string,

         lv_HTTP_CODE type i,

*JSON conversion

         lo_writer TYPE REF TO cl_sxml_string_writer,

         lv_json_in TYPE xstring,

         lv_json_out TYPE xstring,

         lv_json_string type string,

         lo_conv  type ref to CL_ABAP_CONV_IN_CE,

         lo_conv2 type ref to CL_ABAP_CONV_OUT_CE,

*return parameters and error handlers

         lo_cxroot   TYPE REF TO cx_root,

         lv_message type string,

         lv_PAR1 LIKE  SY-MSGV1,

         lv_PAR2 LIKE  SY-MSGV2,

         lv_PAR3 LIKE  SY-MSGV3,

         ls_return type bapiret2"return structure

[snip]

*set request parameters

       CALL METHOD lo_client->request->SET_CONTENT_TYPE('application/json').

       CALL METHOD lo_client->request->SET_METHOD('POST').

*convert data to JSON

       lo_writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

       CALL TRANSFORMATION id SOURCE routes = lt_RANDMCNALLY_JSON initial_components = 'suppress' RESULT XML lo_writer.

       lv_json_in = lo_writer->get_output( ).

*attach data to body

       CALL METHOD lo_client->request->SET_DATA

         EXPORTING

           data = lv_json_in.

*get JSON text in string format for testing

       CALL METHOD CL_ABAP_CONV_IN_CE=>CREATE

         EXPORTING

           INPUT       = lv_json_in

           ENCODING    = 'UTF-8'

           REPLACEMENT = '?'

           IGNORE_CERR = ABAP_TRUE

         RECEIVING

           CONV        = lo_conv.

       CALL METHOD lo_conv->READ

         IMPORTING

           DATA = lv_json_string.

*send HTTP POST call to RandMcNally webservice

       call method lo_client->send

* exporting  timeout = lc_timeout

        exceptions http_communication_failure  = 1

        http_invalid_state = 2

        http_processing_failed = 3

        others = 4.

       if sy-subrc <> 0.

         CALL METHOD lo_client->get_last_error

           IMPORTING

             message = lv_message.

         CONCATENATE 'HTTP POST:' lv_message into lv_message.

         move lv_message to ls_return-message.

         append ls_return to return.

       endif.

*receive data back

       CALL METHOD lo_client->receive

         EXCEPTIONS

           http_communication_failure = 1

           http_invalid_state         = 2

           http_processing_failed     = 3

           others                     = 4.

*pass errors back, if any

       if sy-subrc <> 0.

         clear ls_return.

         ls_return-type = 'E'.

         CALL METHOD lo_client->get_last_error

           IMPORTING

             message = lv_message.

         move sy-subrc to lv_json_string.

         CONCATENATE 'RECEIVE DATA:' lv_json_string lv_message into ls_return-message SEPARATED BY space.

         append ls_return to return.

       endif.

*get the data (a table in JSON format) from response object

       clear lv_json_out.

       lv_json_out = lo_client->response->GET_DATA( ).

*get the status of the response

       CALL METHOD lo_client->response->GET_STATUS

         IMPORTING

           CODE   = lv_HTTP_CODE

           REASON = lv_HTTP_REASON.

*if response status code not 200 (OK), return error and cease processing

       if lv_http_code <> '200'.

         clear ls_return.

         ls_return-type = 'E'.

         move lv_http_code to lv_json_string.

         CONCATENATE 'GET STATUS:' lv_json_string lv_HTTP_REASON into ls_return-message SEPARATED BY space.

         append ls_return to return.

       ENDIF.

     catch cx_root into lo_cxroot.

     cleanup.

       ls_return-message = lo_cxroot->get_text( ).

       append ls_return to return.

   endtry.

*close channel

   CALL METHOD lo_client->close

     EXCEPTIONS

       http_invalid_state = 1

       others             = 2.

*trying to process after error sometimes results in short dump because lv_json_out contains something other than JSON

   if ls_return is not initial.

     return.

   endif.

   if lv_json_out is not initial.

*convert JSON to string and make it UPPERCASE so that SAP can do transformation

     CALL METHOD CL_ABAP_CONV_IN_CE=>CREATE

       EXPORTING

         INPUT       = lv_json_out

         ENCODING    = 'UTF-8'

         REPLACEMENT = '?'

         IGNORE_CERR = ABAP_TRUE

       RECEIVING

         CONV        = lo_conv.

     CALL METHOD lo_conv->READ

       IMPORTING

         DATA = lv_json_string.

     TRANSLATE lv_json_string to UPPER CASE.

*convert JSON back to xstring

     CALL METHOD CL_ABAP_CONV_OUT_CE=>CREATE

       EXPORTING

         ENCODING    = 'UTF-8'

         REPLACEMENT = '?'

         IGNORE_CERR = ABAP_TRUE

       RECEIVING

         CONV        = lo_conv2.

     lo_conv2->convert( EXPORTING data = lv_json_string

                  IMPORTING buffer = lv_json_out ).

*convert our now UPPERCASE xstring to output table (JSON to ABAP)

     clear lt_randmcnally_json.

     lo_writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

     CALL TRANSFORMATION id OPTIONS value_handling = 'accept_decimals_loss'

                            SOURCE XML lv_json_out

                            RESULT routes = lt_RANDMCNALLY_JSON.


[snip]

0 View this answer in context

Helpful Answer

by
Not what you were looking for? View more on this topic or Ask a question