使用“CALL TRANSFORMATION”对 ABAP 中的 null/initial 值进行自定义序列化

Custom serialization of null/initial values in ABAP using `CALL TRANSFORMATION`

您可以使用 CALL TRANSFORMATION 命令将 ABAP 结构序列化为 JSON。是否有可能序列化初始字段的 null 值或忽略初始字段?

TYPES: BEGIN OF t_my_type,
         foo TYPE string,
         bar TYPE string,
       END OF t_my_type.

DATA ls_structure TYPE t_my_type.
ls_structure-foo = 'some value'.
ASSERT ls_structure-bar IS INITIAL.
DATA(lo_json_writer) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION id SOURCE result = ls_structure RESULT XML lo_json_writer.
DATA(lv_json_xstring) = lo_json_writer->get_output( ).
WRITE cl_abap_codepage=>convert_from( source = lv_json_xstring ).

这个最小工作示例的结果是:

{
  "RESULT": {
    "FOO": "some value",
    "BAR": ""
  }
}

在其他语言中(需要处理从 SAP 导出的 json)空字符串 ""null 不一样,需要额外的 processing/handling我想避免。我想要这样的结果

{
  "RESULT": {
    "FOO": "some value",
    "BAR": null
  }
}

或者像这样忽略初始值:

{
  "RESULT": {
    "FOO": "some value"
  }
}

我可以向 CALL TRANSFORMATION 传递一些关于如何处理 null/初始值的附加规则吗?

纯ABAP语言没有空值的概念,除了null references. The most approaching "concept" is the initial value.

用于生成 JSON 格式的 ID 转换永远无法从初始值生成 JSON 值 "null"。空引用的序列化产生 {},其他类型产生 ""(类型 C、STRING、X、XSTRING,最后两个以 base64 表示)、"000..."(类型N)、"0000-00-00"(D 型)、"00:00:00"(T 型)或 0(I、P、F 型、DECFLOAT16、DECFLOAT34、INT1、INT2、INT8)。

要仅序列化非初始值,您可以使用 CALL TRANSFORMATIONoption initial_components = 'suppress':

CALL TRANSFORMATION ID 
  SOURCE result = ls_structure 
  RESULT XML lo_json_writer
  OPTIONS initial_components = 'suppress'.

以下程序演示了 JSON 值的差异,当它们是初始值和非初始值时,以及当使用选项 initial_components = 'suppress' 时。注意:为了序列化数据引用,我不得不使用选项“data_refs = 'heap-or-create'`。

  • 初始值:{"RESULT":{"STRING":"","CHAR4":"","INT":0,"BINFLOAT":0,"DECFLOAT":0,"NUMC4":"0000","DATE":"0000-00-00","TIME":"00:00:00","XSTRING":"","HEX2":"","DREF":{},"OREF":{}}}
  • 初始值+选项initial_components = 'suppress'{"RESULT":{}}
  • 非初始值:{"RESULT":{"STRING":"a ","CHAR4":"b","INT":-1,"BINFLOAT":-2.9999999999999999E-1,"DECFLOAT":-0.3,"NUMC4":"0001","DATE":"2019-11-01","TIME":"10:49:00","XSTRING":"/w==","HEX2":"/w==","DREF":{"%ref":"#d1"},"OREF":{"%ref":"#o10"}},"%heap":{"o10":{"%type":"http://www.sap.com/abapxml/classes/program/ZDEMO_JSON_INITIAL:LCL_CLASS","%val":{"local.LCL_CLASS":{"ATTRIBUTE":"d"}}},"d1":{"%type":"abap:characters","%maxLength":1,"%val":"c"}}}

节目:

REPORT zdemo_json_initial.
TYPES: BEGIN OF t_my_type,
        string   TYPE string,
        char4    TYPE c LENGTH 4,
        int      TYPE i,
        binfloat TYPE f,
        decfloat TYPE decfloat16,
        numc4    TYPE n LENGTH 4,
        date     TYPE d,
        time     TYPE t,
        xstring  TYPE xstring,
        hex2     TYPE x LENGTH 2,
        dref     TYPE REF TO data,
        oref     TYPE REF TO object,
      END OF t_my_type.
CLASS lcl_class DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_serializable_object.
    DATA attribute TYPE string.
ENDCLASS.

DATA(initial) = value t_my_type( ).
DATA(oref) = NEW lcl_class( ).
oref->attribute = 'd'.
DATA(non_initial) = VALUE t_my_type( string = `a ` char4 = `b ` int = -1 binfloat = '-0.3'
    decfloat = '-0.3' numc4 = '1' date = '20191101' time = '104900'
    xstring = 'FF' hex2 = 'FF' dref = REF #( 'c' ) oref = oref ).

DATA(lo_json_writer1) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION id SOURCE result = initial RESULT XML lo_json_writer1
    OPTIONS data_refs = 'heap-or-create'.
DATA(json_initial) = lo_json_writer1->get_output( ).

DATA(lo_json_writer2) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION id SOURCE result = initial RESULT XML lo_json_writer2
    OPTIONS data_refs = 'heap-or-create' INITIAL_COMPONENTS = 'suppress'.
DATA(json_initial_suppress) = lo_json_writer2->get_output( ).

DATA(lo_json_writer3) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
CALL TRANSFORMATION id SOURCE result = non_initial RESULT XML lo_json_writer3
    OPTIONS data_refs = 'heap-or-create'.
DATA(json_non_initial) = lo_json_writer3->get_output( ).

如果您使用更新的系统,您可以使用/ui2/cl_jsonclass。否则,您可以使用 json.abap 库。