EPO Consulting Wiki - Strip JSON output for ABAP structures

Abap strip is a method to remove structure elements at runtime (creating a new structure via runtime). This is useful, when a webservice returns a potentially large structure, where each response uses only a fraction of the whole structure.

This is an old version of this page. To the new page please click here

Das ist eine alte Version dieser Seite. Zur neuen Seite klicken sie hier

class /EPO1/CL_TOOLS, method ABAP_STRIP

This is a static method, and therefore can be called without creating an object of the class:

/epo1/cl_tools=>abap_strip(.. ).

Parameters

Meaning of the ABAP-STRIP - parameters:

  • IS_ANY: a structure to be stripped
  • IT_KEEP: list of elements, which should be kept (this list has the highest priority);
    format of the element names is like in ABAP: ELEMENT-SUB_ELEMENT-SUB_SUB_ELEMENT-..
  • IT_STRIP: list of elements, which should be stripped (except, when listed in IT_KEEP)
    example to strip the CALLSTATUS structure from the result of an GFMC function module: append 'CALLSTATUS' to IT_STRIP
    example to strip the element EV_RESULT from the export - structure of an GFMC function module: append 'EXPORT-EV_RESULT' to IT_STRIP
  • IV_STRIP_INITIAL: if 'X', remove all empty elements (structures, tables, primitive elements)
  • IV_RECURSIVE: if 'X', recurse IV_STRIP_INITIAL to all substructures
  • IV_STRIP_EVERYTHING: if 'X', strip all elements - except when listed in IT_KEEP
  • EV_CHANGED: 'X', if the structure has been changed (else: ' ')
  • ER_ANY: reference to the new structure, filled with the values of the original structure

Note: elements and sub-elements are to be written as in ABAP (e.g. ELEMENT-SUB_ELEMENT-SUB_SUB_ELEMENT-...)

 

examples - how to use

structure, data

The following structure will be used for all examples below:

  TYPES:
    BEGIN OF lty_sub_struc,
      name  TYPE string,
      count TYPE i,
    END OF lty_sub_struc,

    BEGIN OF lty_struc,
      sub_1 TYPE lty_sub_struc,
      sub_2 TYPE lty_sub_struc,
      name  TYPE string,
      count TYPE i,
      char  TYPE char10,
      list  TYPE STANDARD TABLE OF string WITH NON-UNIQUE KEY table_line,
    END OF lty_struc.

The following data definition will be used for the examples below:

  FIELD-SYMBOLS:
    <stripped> TYPE any.

  DATA:
    ls_struc    TYPE        lty_struc,
    lr_stripped TYPE REF TO data,
    lt_keep     TYPE        /epo1/ec_string_table,
    lt_strip    TYPE        /epo1/ec_string_table.

 

accessing the stripped structure

Assign the referenced data to a field symbol:

  ASSIGN lr_stripped->* TO <stripped>.

Afterwards, the field symbol may be used like any other structure (e.g. to create a JSON string).

 

using IV_STRIP_INITIAL

Fill the structure only partially, every empty element (of the main structure) should be removed. This might be the most wanted use case:

  " fill the data
  ls_struc-sub_2-name  = 'substructure #2'.
  ls_struc-sub_2-count = 2.
  APPEND 'teststring' TO ls_struc-list.

Data of the structure:

ClipCapIt-200812-131629.PNG


So we would remove the whole SUB_1 structure (but not SUB_2) and the elements NAME, COUNT and CHAR (but not LIST).


Method call:

  /epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IV_STRIP_INITIAL       = 'X'
    IMPORTING
      ER_ANY                 = lr_stripped ).

  ASSIGN lr_stripped->* TO <stripped>.

And the result (assigned to the field symbol '<STRIPPED>')

ClipCapIt-200807-170627.PNG

 

using IV_STRIP_INITIAL on an initial structure

SHOULD NEVER HAPPEN..

When creating a structure with the runtime, there must be at least one element. Whenever a structure is to be created, where there is no element left, we create a dummy element with the name '_'. This may also occur in sub-structures which must be kept, but all elements are to be stripped.

Data of the (empty) structure:

ClipCapIt-200812-131956.PNG

Method call:

  /epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IV_STRIP_INITIAL       = 'X'
    IMPORTING
      ER_ANY                 = lr_stripped ).

  ASSIGN lr_stripped->* TO <stripped>.

So we would have to remove all of the structure elements, which is not possible. A dummy element is created:

ClipCapIt-200807-171316.PNG

 

using IT_KEEP with IV_STRIP_INITIAL

Elements, which are listed in IT_KEEP are handled with highest priority - they are never stripped. Use the ABAP - format to specify any element.

Fill the structure only partially, the main element COUNT should be kept, and the element COUNT of the structure SUB_1. Because the structure SUB_1 is listed in IT_KEEP, the elements of this structure are also evaluated for 'initial' - thus, the element SUB_1-NAME will be removed:

  " fill the data
  ls_struc-sub_2-name  = 'substructure #2'.
  APPEND 'teststring' TO ls_struc-list.

  " elements to keep
  APPEND 'COUNT'       TO lt_keep.
  APPEND 'SUB_1-COUNT' TO lt_keep.

Data of the structure:

ClipCapIt-200812-132845.PNG

Method call:

  /epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IT_KEEP                = lt_keep
      IV_STRIP_INITIAL       = 'X'
    IMPORTING
      ER_ANY                 = lr_stripped ).

And the result (assigned to the field symbol '<STRIPPED>')

ClipCapIt-200812-140202.PNG

Result:

  • all empty elemens of the main structure has been removed
  • the empty element COUNT has survived
  • the empty element NAME of substructure SUB_1 has been removed
  • the empty element COUNT in the substructure SUB_1 has survived
  • the partly filled substructure SUB_2 has survived unchanged (even with the empty element COUNT)

 

using IT_KEEP with IV_STRIP_INITIAL and IV_RECURSIVE

The flag IV_RECURSIVE is only useful with IV_STRIP_INITIAL, as it causes the recursive removal of empty elements.

Fill the structure only partially, the main element COUNT should be kept, and the element COUNT of the structure SUB_1. Because of the flag IV_RECURSIVE, all substructures will be evaluated for empty elements.:

  " fill the data
  ls_struc-sub_2-name  = 'substructure #2'.
  APPEND 'teststring' TO ls_struc-list.

  " elements to keep
  APPEND 'COUNT'       TO lt_keep.
  APPEND 'SUB_1-COUNT' TO lt_keep.

Data of the structure:

ClipCapIt-200812-133655.PNG

So we would remove NAME, COUNT, CHAR and NAME of structure SUB_1.

Method call:

  /epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IT_KEEP                = lt_keep
      IV_STRIP_INITIAL       = 'X'
      IV_RECURSIVE           = 'X'
    IMPORTING
      ER_ANY                 = lr_stripped ).

And the result (assigned to the field symbol '<STRIPPED>')

ClipCapIt-200812-134403.PNG

Result:

  • all empty elements of the main structure and substructures has been removed, except when listed in IT_KEEP
  • the empty element COUNT has survived
  • the empty element COUNT in the substructure SUB_1 has survived

 

using IT_STRIP

The table 'IT_STRIP' can be used to remove very special elements of a structure. This is independing, if that elements are empty or not.

This might be useful, when only a few elements should be removed.

  " fill the data
  ls_struc-sub_2-name  = 'substructure #2'.
  APPEND 'teststring' TO ls_struc-list.

  " elements to strip
  APPEND 'COUNT'       TO lt_strip.
  APPEND 'SUB_1-COUNT' TO lt_strip.
  APPEND 'SUB_2'       TO lt_strip.

Data of the structure:

ClipCapIt-200812-145716.PNG

We expect, that the listed elements are removed (even if not initial)

Method call:

/epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IT_STRIP               = lt_strip
    IMPORTING
      ER_ANY                 = lr_stripped ).

Result:

ClipCapIt-200807-170117.PNG

The elements, listed in IT_STRIP, has been removed without touching the initial elements NAME, CHAR, etc.

 

using IV_STRIP_EVERYTHING together with IT_KEEP

The flag IV_STRIP_EVERYTHING is meant to really remove all elements. This is useful in combination with IT_KEEP, where few structure elements should be kept - and everything else removed.

Fill the data:

  " fill the data
  ls_struc-sub_2-name  = 'substructure #2'.
  ls_struc-sub_2-count = 2.
  APPEND 'teststring' TO ls_struc-list.

  " elements to keep
  APPEND 'SUB_2' TO lt_keep.
  APPEND 'COUNT' TO lt_keep.

Data of the structure:

ClipCapIt-200812-153236.PNG

..strip everything (red), which is not contained in IT_KEEP (green)

Method call:

  /epo1/cl_tools=>abap_strip(
    EXPORTING
      IS_ANY                 = ls_struc
      IT_KEEP                = it_keep
      IV_STRIP_EVERYTHING    = 'X'
    IMPORTING
      ER_ANY                 = lr_stripped )

And the result:

ClipCapIt-200812-153507.PNG

 

complete report sourcecode

Just to have a really complete coding (for simple copy/paste - and playing around) of the report 'Z_ABAP_STRIP'; the final breakpoint will invoke the debugger, where You can inspect the results:

 1*&---------------------------------------------------------------------*
 2*& Report Z_ABAP_STRIP
 3*&---------------------------------------------------------------------*
 4*&
 5*&---------------------------------------------------------------------*
 6REPORT Z_ABAP_STRIP.
 7
 8  TYPES:
 9    BEGIN OF lty_sub_struc,
10      name  TYPE string,
11      count TYPE i,
12    END OF lty_sub_struc,
13
14    BEGIN OF lty_struc,
15      sub_1 TYPE lty_sub_struc,
16      sub_2 TYPE lty_sub_struc,
17      name  TYPE string,
18      count TYPE i,
19      char  TYPE char10,
20      list  TYPE STANDARD TABLE OF string WITH NON-UNIQUE KEY table_line,
21    END OF lty_struc.
22
23  FIELD-SYMBOLS:
24    <stripped> TYPE any.
25
26  DATA:
27    ls_struc    TYPE        lty_struc,
28    lr_stripped TYPE REF TO data,
29    lt_keep     TYPE        /epo1/ec_string_table,
30    lt_strip    TYPE        /epo1/ec_string_table.
31
32
33  " fill the data
34*  ls_struc-name        = 'TEST'.
35*  ls_struc-count       = 5.
36*  ls_struc-eins-name   = 'ONE'.
37*  ls_struc-eins-count  = 1.
38*  ls_struc-sub_2-name  = 'substructure #2'.
39*  ls_struc-sub_2-count = 2.
40*  APPEND 'teststring' TO ls_struc-list.
41
42  " elements to keep
43*  APPEND 'COUNT'       TO lt_keep.
44*  APPEND 'SUB_1-COUNT' TO lt_keep.
45*  APPEND 'SUB_2'       TO lt_keep.
46*  APPEND 'COUNT'       TO lt_keep.
47
48  " elements to strip
49*  APPEND 'COUNT'       TO lt_strip.
50*  APPEND 'SUB_1-COUNT' TO lt_strip.
51*  APPEND 'SUB_2'       TO lt_strip.
52
53  " get the stripped structure
54  /epo1/cl_tools=>abap_strip(
55    EXPORTING
56      IS_ANY                 = ls_struc
57      IT_KEEP                = lt_keep
58*      IT_STRIP               = lt_strip
59*      IV_STRIP_INITIAL       = 'X'
60*      IV_STRIP_EVERYTHING    = 'X'
61*      IV_RECURSIVE           = 'X'
62    IMPORTING
63      ER_ANY                 = lr_stripped ).
64
65  ASSIGN lr_stripped->* TO <stripped>.

 

creating JSON strings

As an example, the stripped ABAP structure could be used to create a JSON string, using the static method /EPO1/CL_TOOLS=>ABAP_TO_JSON. For details, see our WIKI page JSON_API_in_SAP_ABAP.

Example: Stripping JSON Request for Outbound web service

In this example a JSON REST cloud service is called. Before the send call, the request json is stripped.

The class used for sending (CALL METHOD me->call_service) is /EPO1/CL_JSON_BASE_OUT.

 1  METHOD send.
 2    DATA ls_outgoinginvoice TYPE zcreateoutgoinginvoice.
 3    DATA ls_bapiret2 TYPE bapiret2.
 4    DATA lr_data TYPE REF TO data.
 5    FIELD-SYMBOLS <request> TYPE any.
 6
 7    me->mv_service_id = 'SEND2CLOUD'.
 8    me->mv_service_operation = 'CreateOutgoingInvoice'.
 9
10    CALL METHOD me->fill_outgoinginvoice_send
11      EXPORTING
12        is_invoice         = is_invoice
13        is_ubl21           = is_ubl21
14        is_ublcn21         = is_ublcn21
15        is_file_invoice    = is_file_invoice
16        is_file_attachment = is_file_attachment
17      IMPORTING
18        es_outgoinginvoice = ls_outgoinginvoice
19        es_bapiret2        = ls_bapiret2.
20
21    IF ls_bapiret2 IS INITIAL.
22      CALL METHOD /epo1/cl_tools=>abap_strip
23        EXPORTING
24          is_any           = ls_outgoinginvoice
25*         it_keep          =
26*         it_strip         = lt_strip
27          iv_strip_initial = 'X'
28          iv_recursive     = 'X'
29*         iv_strip_everything =
30        IMPORTING
31*         ev_changed       =
32          er_any           = lr_data.
33
34      ASSIGN lr_data->* TO <request>.
35
36      CALL METHOD me->call_service
37        EXPORTING
38          is_outgoinginvoice = <request>
39        IMPORTING
40          es_bapiret2        = es_bapiret2.
41    ELSE.
42      es_bapiret2-id  = 'ZINV'.
43      es_bapiret2-number = '000'.
44      es_bapiret2-type    = 'E'.
45      es_bapiret2-message =  'error: No Invoice found'..
46      es_bapiret2-message_v1  = es_bapiret2-message.
47    ENDIF.
48
49  ENDMETHOD.