‎2015 Oct 12 11:49 AM
I my report program there is a json string.
[{"duration":258,"length":2051,"status":6},{"duration":333,"length":1623,"status":6},{"duration":523,"length":3367,"status":6},{"duration":540,"length":2921,"status":6},{"duration":380,"length":1302,"status":6},{"duration":1008,"length":4570,"status":6},{"duration":271,"length":1942,"status":6},{"duration":629,"length":3981,"status":6},{"duration":925,"length":4280,"status":6},{"duration":646,"length":3895,"status":6},{"duration":923,"length":4839,"status":6},{"duration":611,"length":2896,"status":6},{"duration":692,"length":3143,"status":6},{"duration":747,"length":3307,"status":6},{"duration":380,"length":2414,"status":6},{"duration":1125,"length":4977,"status":6},{"duration":484,"length":5832,"status":6},{"duration":384,"length":1229,"status":6},{"duration":459,"length":3908,"status":6},{"duration":1216,"length":4664,"status":6},{"duration":299,"length":2244,"status":6},{"duration":751,"length":3442,"status":6},{"duration":1487,"length":6676,"status":6},{"duration":1022,"length":5333,"status":6},{"duration":1620,"length":6792,"status":6},{"duration":1241,"length":6961,"status":6},{"duration":741,"length":4309,"status":6},{"duration":1540,"length":6069,"status":6},{"duration":1578,"length":6580,"status":6},{"duration":890,"length":5754,"status":6},{"duration":488,"length":2902,"status":6},{"duration":288,"length":2785,"status":6},{"duration":562,"length":2016,"status":6},{"duration":756,"length":3454,"status":6},{"duration":478,"length":3712,"status":6},{"duration":1291,"length":4702,"status":6},{"duration":734,"length":5289,"status":6},{"duration":719,"length":4823,"status":6},{"duration":1481,"length":7950,"status":6},{"duration":435,"length":3299,"status":6},{"duration":207,"length":1704,"status":6},{"duration":1197,"length":5029,"status":6},{"duration":561,"length":4100,"status":6},{"duration":609,"length":6206,"status":6},{"duration":858,"length":5799,"status":6},{"duration":1098,"length":8816,"status":6},{"duration":2024,"length":10465,"status":6},{"duration":2649,"length":9847,"status":6},{"duration":1106,"length":8252,"status":6},{"duration":608,"length":3442,"status":6},{"duration":717,"length":4396,"status":6},{"duration":852,"length":6764,"status":6},{"duration":651,"length":5122,"status":6},{"duration":1657,"length":6967,"status":6},{"duration":1059,"length":5298,"status":6},{"duration":1730,"length":8068,"status":6},{"duration":1444,"length":7038,"status":6},{"duration":908,"length":7140,"status":6},{"duration":663,"length":6908,"status":6},{"duration":663,"length":6908,"status":6}]
But here, there is no array name. I have created an internal table with the fields duration, length and name. I want to save the data on to the internal table. When I do CALL TRANSFORMATION it results in runtime error. Can anyone tell how to move these values to the internal table?
‎2015 Oct 12 3:30 PM
Hello Ashok,
Please find below code,
Let me know if that's work for you...
Pass the table which has all required field.
| CALL METHOD json2abap | ||
| EXPORTING | ||
| json_string = jsondata | ||
| var_name | = 'items' | |
| CHANGING | ||
| abap_data = lt_order_data. |
method JSON2ABAP.
*/************************************************/*
*/ Input any abap data and this method tries to /*
*/ fill it with the data in the JSON string. /*
*/ Thanks to Juan Diaz for helping here!! /*
*/************************************************/*
type-pools: abap, js.
data:
js_script type string,
js_started type i value 0,
l_json_string type string,
js_property_table type js_property_tab,
js_property type line of js_property_tab,
l_property_path type string,
item_path type string.
data:
l_type type c,
l_value type string,
linetype type string,
l_comp type line of ABAP_COMPDESCR_TAB.
data:
datadesc type ref to CL_ABAP_TYPEDESCR,
drefdesc type ref to CL_ABAP_TYPEDESCR,
linedesc type ref to CL_ABAP_TYPEDESCR,
strudesc type ref to CL_ABAP_STRUCTDESCR,
tabldesc type ref to CL_ABAP_TABLEDESCR.
data newline type ref to data.
field-symbols:
<abap_data> type any,
<itab> type any table,
<comp> type any,
<jsprop> type line of js_property_tab,
<abapcomp> type abap_compdescr.
define assign_scalar_value.
" &1 <abap_data>
" &2 js_property-value
describe field &1 type l_type.
l_value = &2.
* convert or adapt scalar values to ABAP.
case l_type.
when 'D'. " date type
if l_value cs '-'.
replace all occurrences of '-' in l_value with space.
condense l_value no-gaps.
endif.
when 'T'. " time type
if l_value cs ':'.
replace all occurrences of ':' in l_value with space.
condense l_value no-gaps.
endif.
when others.
" may be other conversions or checks could be implemented here.
endcase.
&1 = l_value.
end-of-definition.
if js_object is not bound.
if json_string is initial. exit. endif. " exit method if there is nothing to parse
l_json_string = json_string.
js_object = cl_java_script=>create( ).
***************************************************
* Parse JSON using JavaScript *
***************************************************
js_object->bind( exporting name_obj = 'abap_data' name_prop = 'json_string' changing data = l_json_string ).
js_object->bind( exporting name_obj = 'abap_data' name_prop = 'script_started' changing data = js_started ).
* We use the JavaScript engine included in ABAP to read the JSON string.
* We simply use the recommended way to eval a JSON string as specified
* in RFC 4627 (http://www.ietf.org/rfc/rfc4627.txt).
*
* Security considerations:
*
* Generally there are security issues with scripting languages. JSON
* is a subset of JavaScript, but it is a safe subset that excludes
* assignment and invocation.
*
* A JSON text can be safely passed into JavaScript's eval() function
* (which compiles and executes a string) if all the characters not
* enclosed in strings are in the set of characters that form JSON
* tokens. This can be quickly determined in JavaScript with two
* regular expressions and calls to the test and replace methods.
*
* var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
* text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
* eval('(' + text + ')');
concatenate
'var json_obj; '
'var json_text; '
'function start() { '
' if(abap_data.script_started) { return; } '
' json_text = abap_data.json_string;'
' json_obj = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( '
' json_text.replace(/"(\\.|[^"\\])*"/g, ''''))) && '
' eval(''('' + json_text + '')''); '
' abap_data.script_started = 1; '
'} '
'if(!abap_data.script_started) start(); '
into js_script respecting blanks separated by xnl.
js_object->compile( script_name = 'json_parser' script = js_script ).
js_object->execute( script_name = 'json_parser' ).
if js_object->last_error_message is not initial.
" RAISE EXCEPTION
endif.
endif.
*
* Get ABAP data type, dereference if necessary and start
datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA( abap_data ).
if datadesc->kind eq cl_abap_typedescr=>kind_ref.
assign abap_data->* to <abap_data>.
else.
assign abap_data to <abap_data>.
endif.
datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA( <abap_data> ).
**
if var_name is not initial.
concatenate property_path var_name into l_property_path separated by '.'.
else.
l_property_path = property_path.
endif.
**
js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).
* If the table is empty, try with the lowercase name of the param, to increase the chances of a match.
if js_property_table is initial.
translate l_property_path to lower case.
js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).
endif.
case datadesc->kind.
when cl_abap_typedescr=>kind_elem.
* Scalar: process ABAP elements. Assume no type conversions for the moment.
if var_name is initial.
RAISE EXCEPTION type zcx_json
EXPORTING
message = 'VAR_NAME is required for scalar values.'.
endif.
js_property_table = js_object->get_properties_scope_global( property_path = property_path ).
read table js_property_table with key name = var_name into js_property.
if sy-subrc eq 0.
assign_scalar_value <abap_data> js_property-value.
endif.
when cl_abap_typedescr=>kind_struct.
* Translate JS properties to upper case. This is risky, but necessary
* if we want a little interoperability with ABAP structures.
loop at js_property_table assigning <jsprop>.
translate <jsprop>-name to upper case.
endloop.
* Process ABAP structures
strudesc ?= datadesc.
loop at strudesc->COMPONENTS into l_comp.
assign component l_comp-name of structure <abap_data> to <comp>.
case l_comp-type_kind.
when cl_abap_typedescr=>TYPEKIND_STRUCT1 " 'v'
or cl_abap_typedescr=>TYPEKIND_STRUCT2 " 'u'
or cl_abap_typedescr=>TYPEKIND_TABLE. " 'h' (may need a different treatment one day)
concatenate l_property_path l_comp-name into item_path separated by '.'.
*> Recursive call here
json2abap( exporting property_path = item_path changing abap_data = <comp> js_object = js_object ).
** when cl_abap_typedescr=>TYPEKIND_TABLE. " 'h' (may need a different treatment one day)
when others.
* Process scalars in structures (same as the kind_elem above)
read table js_property_table with key name = l_comp-name into js_property.
if sy-subrc eq 0.
assign_scalar_value <comp> js_property-value.
endif.
endcase.
endloop.
when cl_abap_typedescr=>kind_table.
* Process ABAP tables
if js_property_table is not initial.
tabldesc ?= datadesc.
linedesc = tabldesc->get_table_line_type( ).
linetype = linedesc->get_relative_name( ).
assign <abap_data> to <itab>.
DELETE js_property_table WHERE kind NE 'O'.
loop at js_property_table into js_property.
create data newline type (linetype).
concatenate l_property_path js_property-name into item_path separated by '.'.
condense item_path.
*> Recursive call here
json2abap( exporting property_path = item_path changing abap_data = newline js_object = js_object ).
assign newline->* to <comp>.
insert <comp> into table <itab>.
free newline.
endloop.
endif.
when others. " kind_class, kind_intf
" forget it.
endcase.
endmethod.
Hopefully this will help.
Thanks,
Nikhil
‎2015 Oct 12 3:30 PM
Hello Ashok,
Please find below code,
Let me know if that's work for you...
Pass the table which has all required field.
| CALL METHOD json2abap | ||
| EXPORTING | ||
| json_string = jsondata | ||
| var_name | = 'items' | |
| CHANGING | ||
| abap_data = lt_order_data. |
method JSON2ABAP.
*/************************************************/*
*/ Input any abap data and this method tries to /*
*/ fill it with the data in the JSON string. /*
*/ Thanks to Juan Diaz for helping here!! /*
*/************************************************/*
type-pools: abap, js.
data:
js_script type string,
js_started type i value 0,
l_json_string type string,
js_property_table type js_property_tab,
js_property type line of js_property_tab,
l_property_path type string,
item_path type string.
data:
l_type type c,
l_value type string,
linetype type string,
l_comp type line of ABAP_COMPDESCR_TAB.
data:
datadesc type ref to CL_ABAP_TYPEDESCR,
drefdesc type ref to CL_ABAP_TYPEDESCR,
linedesc type ref to CL_ABAP_TYPEDESCR,
strudesc type ref to CL_ABAP_STRUCTDESCR,
tabldesc type ref to CL_ABAP_TABLEDESCR.
data newline type ref to data.
field-symbols:
<abap_data> type any,
<itab> type any table,
<comp> type any,
<jsprop> type line of js_property_tab,
<abapcomp> type abap_compdescr.
define assign_scalar_value.
" &1 <abap_data>
" &2 js_property-value
describe field &1 type l_type.
l_value = &2.
* convert or adapt scalar values to ABAP.
case l_type.
when 'D'. " date type
if l_value cs '-'.
replace all occurrences of '-' in l_value with space.
condense l_value no-gaps.
endif.
when 'T'. " time type
if l_value cs ':'.
replace all occurrences of ':' in l_value with space.
condense l_value no-gaps.
endif.
when others.
" may be other conversions or checks could be implemented here.
endcase.
&1 = l_value.
end-of-definition.
if js_object is not bound.
if json_string is initial. exit. endif. " exit method if there is nothing to parse
l_json_string = json_string.
js_object = cl_java_script=>create( ).
***************************************************
* Parse JSON using JavaScript *
***************************************************
js_object->bind( exporting name_obj = 'abap_data' name_prop = 'json_string' changing data = l_json_string ).
js_object->bind( exporting name_obj = 'abap_data' name_prop = 'script_started' changing data = js_started ).
* We use the JavaScript engine included in ABAP to read the JSON string.
* We simply use the recommended way to eval a JSON string as specified
* in RFC 4627 (http://www.ietf.org/rfc/rfc4627.txt).
*
* Security considerations:
*
* Generally there are security issues with scripting languages. JSON
* is a subset of JavaScript, but it is a safe subset that excludes
* assignment and invocation.
*
* A JSON text can be safely passed into JavaScript's eval() function
* (which compiles and executes a string) if all the characters not
* enclosed in strings are in the set of characters that form JSON
* tokens. This can be quickly determined in JavaScript with two
* regular expressions and calls to the test and replace methods.
*
* var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
* text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
* eval('(' + text + ')');
concatenate
'var json_obj; '
'var json_text; '
'function start() { '
' if(abap_data.script_started) { return; } '
' json_text = abap_data.json_string;'
' json_obj = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( '
' json_text.replace(/"(\\.|[^"\\])*"/g, ''''))) && '
' eval(''('' + json_text + '')''); '
' abap_data.script_started = 1; '
'} '
'if(!abap_data.script_started) start(); '
into js_script respecting blanks separated by xnl.
js_object->compile( script_name = 'json_parser' script = js_script ).
js_object->execute( script_name = 'json_parser' ).
if js_object->last_error_message is not initial.
" RAISE EXCEPTION
endif.
endif.
*
* Get ABAP data type, dereference if necessary and start
datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA( abap_data ).
if datadesc->kind eq cl_abap_typedescr=>kind_ref.
assign abap_data->* to <abap_data>.
else.
assign abap_data to <abap_data>.
endif.
datadesc = cl_abap_typedescr=>DESCRIBE_BY_DATA( <abap_data> ).
**
if var_name is not initial.
concatenate property_path var_name into l_property_path separated by '.'.
else.
l_property_path = property_path.
endif.
**
js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).
* If the table is empty, try with the lowercase name of the param, to increase the chances of a match.
if js_property_table is initial.
translate l_property_path to lower case.
js_property_table = js_object->get_properties_scope_global( property_path = l_property_path ).
endif.
case datadesc->kind.
when cl_abap_typedescr=>kind_elem.
* Scalar: process ABAP elements. Assume no type conversions for the moment.
if var_name is initial.
RAISE EXCEPTION type zcx_json
EXPORTING
message = 'VAR_NAME is required for scalar values.'.
endif.
js_property_table = js_object->get_properties_scope_global( property_path = property_path ).
read table js_property_table with key name = var_name into js_property.
if sy-subrc eq 0.
assign_scalar_value <abap_data> js_property-value.
endif.
when cl_abap_typedescr=>kind_struct.
* Translate JS properties to upper case. This is risky, but necessary
* if we want a little interoperability with ABAP structures.
loop at js_property_table assigning <jsprop>.
translate <jsprop>-name to upper case.
endloop.
* Process ABAP structures
strudesc ?= datadesc.
loop at strudesc->COMPONENTS into l_comp.
assign component l_comp-name of structure <abap_data> to <comp>.
case l_comp-type_kind.
when cl_abap_typedescr=>TYPEKIND_STRUCT1 " 'v'
or cl_abap_typedescr=>TYPEKIND_STRUCT2 " 'u'
or cl_abap_typedescr=>TYPEKIND_TABLE. " 'h' (may need a different treatment one day)
concatenate l_property_path l_comp-name into item_path separated by '.'.
*> Recursive call here
json2abap( exporting property_path = item_path changing abap_data = <comp> js_object = js_object ).
** when cl_abap_typedescr=>TYPEKIND_TABLE. " 'h' (may need a different treatment one day)
when others.
* Process scalars in structures (same as the kind_elem above)
read table js_property_table with key name = l_comp-name into js_property.
if sy-subrc eq 0.
assign_scalar_value <comp> js_property-value.
endif.
endcase.
endloop.
when cl_abap_typedescr=>kind_table.
* Process ABAP tables
if js_property_table is not initial.
tabldesc ?= datadesc.
linedesc = tabldesc->get_table_line_type( ).
linetype = linedesc->get_relative_name( ).
assign <abap_data> to <itab>.
DELETE js_property_table WHERE kind NE 'O'.
loop at js_property_table into js_property.
create data newline type (linetype).
concatenate l_property_path js_property-name into item_path separated by '.'.
condense item_path.
*> Recursive call here
json2abap( exporting property_path = item_path changing abap_data = newline js_object = js_object ).
assign newline->* to <comp>.
insert <comp> into table <itab>.
free newline.
endloop.
endif.
when others. " kind_class, kind_intf
" forget it.
endcase.
endmethod.
Hopefully this will help.
Thanks,
Nikhil