Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- METHOD json_to_data.
- DATA: lv_off TYPE i.
- DATA: lv_len TYPE i.
- DATA: lv_key TYPE string.
- DATA: lv_value TYPE string.
- DATA: lv_char TYPE char1. "Current chacater
- DATA: lv_pchar TYPE char1. "Previous character
- DATA: lv_instr TYPE boole_d. "Indicator: cursor in string
- DATA: lv_level TYPE i. "Depth inside a block
- DATA: lv_table TYPE boole_d.
- FIELD-SYMBOLS: <fk> TYPE string.
- FIELD-SYMBOLS: <data> TYPE ANY.
- FIELD-SYMBOLS: <table> TYPE ANY TABLE.
- FIELD-SYMBOLS: <sotab> TYPE SORTED TABLE.
- FIELD-SYMBOLS: <sttab> TYPE STANDARD TABLE.
- FIELD-SYMBOLS: <line> TYPE ANY.
- DATA: ls_line TYPE REF TO data.
- DATA: lr_td TYPE REF TO cl_abap_typedescr.
- DATA: lr_ttd TYPE REF TO cl_abap_tabledescr.
- * If the incoming json contains no '{}[]', we are dealing with
- * a basic (scalar) value that is simply assigned to the data
- * and then we return
- IF json NA '{}[]'.
- * Replace escape characters (TODO: Check if there are more!)
- lv_value = json.
- REPLACE ALL OCCURRENCES OF '\n' IN lv_value WITH cl_abap_char_utilities=>newline.
- REPLACE ALL OCCURRENCES OF '\t' IN lv_value WITH cl_abap_char_utilities=>horizontal_tab.
- REPLACE ALL OCCURRENCES OF '\f' IN lv_value WITH cl_abap_char_utilities=>form_feed.
- REPLACE ALL OCCURRENCES OF '\v' IN lv_value WITH cl_abap_char_utilities=>vertical_tab.
- REPLACE ALL OCCURRENCES OF '\b' IN lv_value WITH cl_abap_char_utilities=>backspace.
- REPLACE ALL OCCURRENCES OF '\\' IN lv_value WITH '\'.
- * TODO: Deal with specific data types, e.g. dates etc.
- data = lv_value.
- EXIT.
- ENDIF.
- lv_len = STRLEN( json ).
- * Check if we are dealing with a table
- lr_td = cl_abap_typedescr=>describe_by_data( data ).
- IF lr_td->type_kind = cl_abap_typedescr=>typekind_table.
- * This information is used later...
- lv_table = 'X'.
- ASSIGN data TO <table>.
- CREATE DATA ls_line LIKE LINE OF <table>.
- ASSIGN ls_line->* TO <line>.
- ELSE.
- lv_table = ' '.
- ENDIF.
- * Reset counters/flags
- lv_off = 0.
- lv_instr = ' '.
- lv_level = 0.
- ASSIGN lv_key TO <fk>.
- WHILE lv_off < lv_len.
- lv_char = json+lv_off(1).
- **********************************************************************
- * IN STRING
- **********************************************************************
- * Character is in a string delimited by double quotes
- IF lv_instr = 'X'.
- IF lv_char = '"'.
- * Switch out of delimited character string
- IF lv_pchar NE '\'.
- lv_instr = ' '.
- ELSE.
- CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
- ENDIF.
- ELSE.
- CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
- ENDIF.
- **********************************************************************
- * OUTSIDE STRING
- **********************************************************************
- * Character is not in a string delimited by double quotes
- ELSE.
- * On opening character, shift level up
- IF lv_char CA '{['.
- ADD 1 TO lv_level.
- ENDIF.
- * When the value is contained in a {}/[], the entire value must
- * be passed to the next level of processing
- IF lv_level > 1.
- CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
- ELSE.
- IF lv_char CA '[{'. "<- Chars ignored outside of str
- ELSEIF lv_char = ':'.
- ASSIGN lv_value TO <fk>.
- * The key collected up to now is assigned to the data member
- TRANSLATE lv_key TO UPPER CASE.
- SHIFT lv_key LEFT DELETING LEADING space.
- ASSIGN COMPONENT lv_key OF STRUCTURE data TO <data>.
- * End of a key/value pair (we bump up against delimiter) - pass to next level
- ELSEIF ( lv_char = ',' OR lv_char = '}' ) AND lv_table = space.
- * Process collected value
- ****************************** Inizio modifica [ES] 14/04/2016 Se viene letto un campo non contentuto nella struttura, esco dal metodo.
- IF <data> IS NOT ASSIGNED.
- RETURN.
- ENDIF.
- ************************** Fine modifica [ES]
- json_to_data( EXPORTING json = lv_value CHANGING data = <data> ).
- * Clear key and value
- CLEAR: lv_key, lv_value.
- ASSIGN lv_key TO <fk>.
- CLEAR: lv_key, lv_value.
- * End of a key/value pair (we bump up against delimiter) - pass to next level
- * But in table mode, we pass an instance of a row of the table, and afterward
- * add it to the table
- ELSEIF ( lv_char = ',' OR lv_char = ']' ) AND lv_table = 'X'.
- * Process collected value
- * Inside array in JSON, there are no keys, only list of values, the collected
- * value is in lv_key
- SHIFT lv_key LEFT DELETING LEADING space.
- json_to_data( EXPORTING json = lv_key CHANGING data = <line> ).
- * On return: if dealing with table, add the record to the table
- lr_ttd ?= lr_td.
- IF lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_sorted
- OR lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_hashed.
- ASSIGN data TO <sotab>.
- INSERT <line> INTO TABLE <sotab>.
- ELSE.
- ASSIGN data TO <sttab>.
- APPEND <line> TO <sttab>.
- ENDIF.
- CLEAR <line>.
- * Clear key and value
- CLEAR: lv_key, lv_value.
- ASSIGN lv_key TO <fk>.
- CLEAR: lv_key, lv_value.
- * Switch cursor into delimited string; consecutive characters
- * are then treated as part of a key or value, even if they are
- * special characters
- ELSEIF lv_char = '"'.
- lv_instr = 'X'.
- * Other chars processed as either key or value
- ELSE.
- CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
- ENDIF.
- ENDIF.
- * On closing character, shift level down again
- IF lv_char CA '}]'.
- SUBTRACT 1 FROM lv_level.
- ENDIF.
- * END: Are we in string or out?
- ENDIF.
- lv_pchar = lv_char.
- ADD 1 TO lv_off.
- ENDWHILE.
- ENDMETHOD.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement