Hi,
I have come across many scn threads which refer to "How to read / get data from a dynamic node" .
Here I would like to demonstrate, the steps to read the data from a node ( either static / dynamic node ) in Webdynpro ABAP.
I have divided the task into 3 methods
- GET_NODE_INFO( ) - Get node information from node name
- GET_NODE_DATA_TYPE( ) - Get node data type & attribute list by using node reference ( if_wd_context_node )
- GET_DATA( ) - Get data of any given node reference
Now, let us look into the code of each method as below
GET_NODE_INFO( )
Parameters:
Parameter | Type | Ref To | Optional | Associated Type | Description |
---|---|---|---|---|---|
ID_NODE_NAME | Importing | STRING | Node Name | ||
IO_PARENT_NODE | Importing | Checked | Yes | IF_WD_CONTEXT_NODE | Parent Node Reference |
EO_NODE_INFO | Exporting | Checked | IF_WD_CONTEXT_NODE_INFO | Node info reference | |
ED_ERROR_MESSAGE | Exporting | STRING | error message | ||
EO_NODE | Exporting | Checked | IF_WD_CONTEXT_NODE | Node reference |
Logic:
METHOD get_node_info .
DATA: lo_node_info TYPE REF TO if_wd_context_node_info,
lo_parent_node TYPE REF TO if_wd_context_node,
lv_node_name TYPE string,
lx_root TYPE REF TO cx_root.
TRY.
"=============================================
" check if node name is supplied,
" if so nothing do , return the control
"=============================================
IF id_node_name IS INITIAL.
RETURN.
ELSE.
lv_node_name = id_node_name.
TRANSLATE lv_node_name TO UPPER CASE.
ENDIF.
"=============================================
" Check if io_parent_node is not bound, if so
" Assume parent node is WD_CONTEXT
"=============================================
IF io_parent_node IS NOT BOUND.
lo_parent_node = wd_context.
ELSE.
lo_parent_node = io_parent_node.
ENDIF.
"=============================================
"get node info
"=============================================
eo_node = lo_parent_node->get_child_node( name = lv_node_name ).
eo_node_info = eo_node->get_node_info( ).
CATCH cx_root INTO lx_root.
ed_error_message = lx_root->get_text( ).
ENDTRY.
ENDMETHOD.
----------------------------------------------------------
GET_NODE_DATA_TYPE( )
Parameters:
Parameter | Type | Ref To | Optional | Associated Type | Description |
---|---|---|---|---|---|
IO_NODE_INFO | Importing | Checked | IF_WD_CONTEXT_NODE_INFO | Node info Reference | |
ED_ERROR_MESSAGE | Exporting | STRING | Error message | ||
EO_DATA | Exporting | Checked | DATA | Node data type ref | |
ET_FCAT | Exporting | LVC_T_FCAT | Attributes/fields list |
Logic:
METHOD GET_NODE_DATA_TYPE .
CLEAR:
eo_data,
et_fcat,
ed_error_message.
TRY .
DATA:
lo_table TYPE REF TO data,
ls_fcat TYPE lvc_s_fcat,
lt_attr TYPE wdr_context_attr_info_map,
ls_attr LIKE LINE OF lt_attr,
lx_root TYPE REF TO cx_root.
IF io_node_info IS NOT BOUND.
ed_error_message = 'Node info is invalid'.
RETURN.
ENDIF.
"=============================================
" get attributes
"=============================================
lt_attr = io_node_info->get_attributes( ).
LOOP AT lt_attr INTO ls_attr.
CLEAR ls_fcat.
ls_fcat-fieldname = ls_attr-name.
ls_fcat-datatype = ls_attr-type_name.
APPEND ls_fcat TO Et_fcat.
ENDLOOP.
cl_alv_table_create=>create_dynamic_table(
EXPORTING
it_fieldcatalog = Et_fcat
i_length_in_byte = abap_true
IMPORTING
ep_table = lo_table
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2
).
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
" if node is multiple ( 0..n / 1..n ) return table type
IF io_node_info->is_multiple( ) EQ abap_true.
eo_data = lo_table.
ELSE.
FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE.
ASSIGN lo_table->* TO <lt_table>.
IF <lt_table> IS ASSIGNED.
CREATE DATA eo_data LIKE LINE OF <lt_table>.
ENDIF.
" else, return the
ENDIF.
CATCH cx_root INTO lx_root.
ed_error_message = lx_root->get_text( ).
ENDTRY.
ENDMETHOD.
----------------------------------------------------------
GET_DATA( )
Parameters:
Parameter | Type | Ref To | Optional | Associated Type | Description |
---|---|---|---|---|---|
IO_NODE | Importing | Checked | IF_WD_CONTEXT_NODE | Node reference | |
ED_ERROR_MESSAGE | Exporting | STRING | Error message | ||
EO_DATA | Exporting | Checked | DATA | Data | |
ET_FCAT | Exporting | LVC_T_FCAT | Fields |
Logic:
METHOD GET_DATA .
DATA lv_count TYPE i.
DATA ls_fcat TYPE lvc_s_fcat.
DATA lv_index TYPE i.
DATA lv_attr_name TYPE string.
DATA lx_root TYPE REF TO cx_root.
FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE,
<ls_data> TYPE any,
<lv_value> TYPE any.
TRY.
IF io_node IS NOT BOUND.
ed_error_message = 'Node reference cannot be empty'.
RETURN.
ENDIF.
" Get node data type and attribute list
wd_this->get_node_data_type(
EXPORTING
io_node_info = io_node->get_node_info( )
IMPORTING
eo_data = eo_data
et_fcat = et_fcat
ed_error_message = ed_error_message
).
" Return if any error or data type is not bound
IF ed_error_message IS NOT INITIAL OR
eo_data IS NOT BOUND.
RETURN.
ENDIF.
ASSIGN eo_data->* TO <lt_data>.
" get the no. of elements available in context node
lv_count = io_node->get_element_count( ).
" do for each element
DO lv_count TIMES.
" collect index value
lv_index = sy-index.
" Create a blank line and get the ref into <ls_dat>
APPEND INITIAL LINE TO <lt_data> ASSIGNING <ls_data>.
" return if line type is not assigned
IF <ls_data> IS NOT ASSIGNED.
RETURN.
ENDIF.
" Loop over each field/attribute and get the data
LOOP AT et_fcat INTO ls_fcat.
ASSIGN COMPONENT ls_fcat-fieldname
OF STRUCTURE <ls_data> TO <lv_value>.
IF <lv_value> IS ASSIGNED.
lv_attr_name = ls_fcat-fieldname.
io_node->get_attribute(
EXPORTING
index = lv_index
name = lv_attr_name
IMPORTING
value = <lv_value>
).
ENDIF.
ENDLOOP.
ENDDO.
CATCH cx_root INTO lx_root.
ed_error_message = lx_root->get_text( ).
ENDTRY.
ENDMETHOD.
----------------------------------------------------
Example:
Scenario: Let us say we need to read data from a node "NODE_DYN".
--------------------------
" Data declarations
DATA: lo_data TYPE REF TO data.
DATA lo_node TYPE REF TO if_wd_context_node.
FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE.
" Get node information
wd_this->get_node_info(
EXPORTING
id_node_name = 'NODE_DYN'
* io_parent_node =
IMPORTING
* eo_node_info = LO_NODE_INFO
eo_node = lo_node
* ed_error_message =
).
" Get the data from context node
wd_this->get_data(
EXPORTING
io_node = lo_node
IMPORTING
eo_data = lo_data
* et_fcat =
* ed_error_message =
).
" assign data into dynamic table
ASSIGN lo_data->* to <lt_data>.
--------------------------
The internal table <lt_data> contains the data of our node "NODE_DYN"