ABAP и JSON
В ABAP с определённой версии есть поддержка JSON на уровне языка:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
DATA text TYPE string VALUE `Hello JSON, I’m ABAP!`. DATA writer TYPE REF TO cl_sxml_string_writer. DATA json TYPE xstring. “ABAP to JSON writer = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ). CALL TRANSFORMATION id SOURCE text = text RESULT XML writer. json = writer->get_output( ). “JSON to ABAP text = `{“TEXT”:”Hello ABAP, I’m JSON!”}`. CALL TRANSFORMATION id SOURCE XML text RESULT text = text. |
Парсинг JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
CLASS lcl_json_parser DEFINITION. PUBLIC SECTION. TYPES: BEGIN OF ty_node, type TYPE string, prefix TYPE string, name TYPE string, nsuri TYPE string, value TYPE string, value_raw TYPE xstring, END OF ty_node. TYPES: ty_it_node TYPE STANDARD TABLE OF ty_node WITH DEFAULT KEY. CONSTANTS: co_open_element TYPE string VALUE 'OPEN'. CONSTANTS: co_close_element TYPE string VALUE 'CLOSE'. CONSTANTS: co_attribute TYPE string VALUE 'ATTRIBUTE'. CONSTANTS: co_value TYPE string VALUE 'VALUE'. CLASS-METHODS: convert_json_to_node_table IMPORTING iv_json TYPE string RETURNING VALUE(rv_it_nodes) TYPE ty_it_node RAISING cx_sxml_parse_error. ENDCLASS. CLASS lcl_json_parser IMPLEMENTATION. METHOD convert_json_to_node_table. DATA(o_json) = cl_abap_codepage=>convert_to( iv_json ). DATA(o_reader) = cl_sxml_string_reader=>create( o_json ). TRY. DATA(o_node) = o_reader->read_next_node( ). WHILE o_node IS BOUND. CASE o_node->type. WHEN if_sxml_node=>co_nt_element_open. DATA(op) = CAST if_sxml_open_element( o_node ). APPEND VALUE #( type = co_open_element prefix = op->prefix name = op->qname-name nsuri = op->qname-namespace ) TO rv_it_nodes. LOOP AT op->get_attributes( ) ASSIGNING FIELD-SYMBOL(<a>). APPEND VALUE #( type = co_attribute prefix = <a>->prefix name = <a>->qname-name nsuri = <a>->qname-namespace value = COND #( WHEN <a>->value_type = if_sxml_value=>co_vt_text THEN <a>->get_value( ) ) value_raw = COND #( WHEN <a>->value_type = if_sxml_value=>co_vt_raw THEN <a>->get_value_raw( ) ) ) TO rv_it_nodes. ENDLOOP. WHEN if_sxml_node=>co_nt_element_close. DATA(cl) = CAST if_sxml_close_element( o_node ). APPEND VALUE #( type = co_close_element prefix = cl->prefix name = cl->qname-name nsuri = cl->qname-namespace ) TO rv_it_nodes. WHEN if_sxml_node=>co_nt_value. DATA(val) = CAST if_sxml_value_node( o_node ). APPEND VALUE #( type = co_value value = COND #( WHEN val->value_type = if_sxml_value=>co_vt_text THEN val->get_value( ) ) value_raw = COND #( WHEN val->value_type = if_sxml_value=>co_vt_raw THEN val->get_value_raw( ) ) ) TO rv_it_nodes. WHEN OTHERS. ENDCASE. o_node = o_reader->read_next_node( ). ENDWHILE. CATCH cx_root INTO DATA(e_txt). RAISE EXCEPTION TYPE cx_sxml_parse_error EXPORTING error_text = e_txt->get_text( ). ENDTRY. ENDMETHOD. ENDCLASS. START-OF-SELECTION. TRY. DATA(lv_json) = CONV string( '{"VALUES":[{"NAME":"Horst","TITLE":"Herr","AGE":30},{"NAME":"Jutta","TITLE":"Frau","AGE":35},{"NAME":"Ingo","TITLE":"Herr","AGE":31}]}' ). DATA(it_node_values) = lcl_json_parser=>convert_json_to_node_table( lv_json ). cl_demo_output=>write_data( lv_json ). cl_demo_output=>write_data( it_node_values ). cl_demo_output=>display( ). CATCH cx_root INTO DATA(e_txt). WRITE: / e_txt->get_text( ). ENDTRY. |
Однако каноничное представление JSON по той или иной причине может не подойти. В качестве альтернативы есть множество стандартных API по формированию JSON:
- /ui2/cl_json
- /ui5/cl_json_parser
- /ui2/cl_abap2json
- cl_clb_parse_json
- cl_fdt_json
- cl_trex_json_serializer
Так же есть сторонние разработки: