使用“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 TRANSFORMATION
的 option 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 库。
您可以使用 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 TRANSFORMATION
的 option 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 库。