Search code examples
jsonabapjson-serialization

Customize JSON created by CL_SXML_STRING_WRITER


I create JSON like this to extract any table (name "randomly" decided at runtime, its name is in variable iv_table_name):

FIELD-SYMBOLS <itab> TYPE STANDARD TABLE.
DATA ref_itab TYPE REF TO data.

DATA(iv_table_name) = 'SCARR'.
CREATE DATA ref_itab TYPE STANDARD TABLE OF (iv_table_name).
ASSIGN ref_itab->* TO <itab>.

SELECT *
  INTO TABLE <itab>
  FROM (iv_table_name).

DATA results_json TYPE TABLE OF string.
DATA sub_json TYPE string.

DATA(lo_json_writer) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

CALL TRANSFORMATION id
        SOURCE result = <itab>
        RESULT XML lo_json_writer.

cl_abap_conv_in_ce=>create( )->convert( 
        EXPORTING
          input = lo_json_writer->get_output( )
        IMPORTING
          data = sub_json ).

The result variable sub_json looks like this:

{"RESULT":
 [
   {"MANDT":"220","AUFNR":"0000012", ...},
   {"MANDT":"220","AUFNR":"0000013", ...},
   ...
  ]
}

Is there a way to avoid the surrounding dictionary and get the result like this?

 [
   {"MANDT":"220","AUFNR":"0000012", ...},
   {"MANDT":"220","AUFNR":"0000013", ...},
   ...
  ]

Background:

I used this:

sub_json = /ui2/cl_json=>serialize( data = <lt_result> pretty_name = /ui2/cl_json=>pretty_mode-low_case ).

But the performance of /ui2/cl_json=>serialize( ) is not good.


Solution

  • I've got no answer whether it's possible to omit the initial "RESULT" tag in full sXML, but my opinion is NO.

    Now, there's the solution with the KISS principle :

    REPLACE ALL OCCURRENCES OF REGEX '^\{"RESULT":|\}$' IN sub_json WITH ``.
    

    There's also this other writing (slightly slower):

    sub_json = replace( val = sub_json regex = '^\{"RESULT":|\}$' with = `` occ = 0 ).
    

    ADDENDUM about performance:

    I measured that for a string of 880K characters, the following code with the exact number of positions to remove (10 leading characters and 1 trailing character) is 6 times faster than regex (could vary based on version of ABAP kernel), but maybe it won't be noticeable compared to the rest of the program:

    SHIFT sub_json LEFT BY 10 PLACES CIRCULAR.
    REPLACE SECTION OFFSET strlen( sub_json ) - 11 OF sub_json WITH ``.