REPORT zpj_xml_parse.
TYPE-POOLS: ixml.
CLASS cl_ixml DEFINITION LOAD.
CONSTANTS: c_tab(1) TYPE x VALUE '09',
c_break(2) TYPE x VALUE '0D0A'.
TYPES: BEGIN OF t_xml_line,
data(256) TYPE x,
END OF t_xml_line.
DATA: g_ixml TYPE REF TO if_ixml,
g_streamfactory TYPE REF TO if_ixml_stream_factory,
g_parser TYPE REF TO if_ixml_parser,
g_istream TYPE REF TO if_ixml_istream,
g_document TYPE REF TO if_ixml_document,
g_node TYPE REF TO if_ixml_node,
g_xmldata TYPE string,
g_error TYPE xfeld.
DATA: g_elem TYPE REF TO if_ixml_element,
g_root_node TYPE REF TO if_ixml_node,
g_next_node TYPE REF TO if_ixml_node,
g_name TYPE string,
g_iterator TYPE REF TO if_ixml_node_iterator.
DATA: g_xml_table TYPE TABLE OF t_xml_line,
g_xml_line TYPE t_xml_line,
g_xml_table_size TYPE i.
SELECTION-SCREEN: BEGIN OF BLOCK b0 WITH FRAME TITLE text-000.
SELECTION-SCREEN: BEGIN OF BLOCK b2 WITH FRAME TITLE text-002.
PARAMETERS: p_input LIKE rlgrap-filename DEFAULT 'C:\temp\flights2.xml'.
SELECTION-SCREEN: END OF BLOCK b2.
SELECTION-SCREEN: END OF BLOCK b0.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_input.
PERFORM get_file_name USING ',*.XML.' CHANGING p_input.
START-OF-SELECTION.
g_ixml = cl_ixml=>create( ).
g_streamfactory = g_ixml->create_stream_factory( ).
PERFORM get_xml_table CHANGING g_xml_table_size g_xml_table.
g_istream = g_streamfactory->create_istream_itable(
table = g_xml_table
size = g_xml_table_size ).
g_document = g_ixml->create_document( ).
PERFORM parse_document.
CHECK g_error = space.
IF g_parser->is_dom_generating( ) EQ 'X'.
PERFORM process_dom USING g_document.
ENDIF.
FORM parse_document.
DATA: parseerror TYPE REF TO if_ixml_parse_error,
str TYPE string,
i TYPE i,
count TYPE i,
index TYPE i.
g_parser = g_ixml->create_parser( stream_factory = g_streamfactory
istream = g_istream
document = g_document ).
IF g_parser->parse( ) NE 0.
g_error = 'X'.
IF g_parser->num_errors( ) NE 0.
count = g_parser->num_errors( ).
ULINE.
WRITE: count, ' parse errors have occured:'.
index = 0.
WHILE index < count.
parseerror = g_parser->get_error( index = index ).
i = parseerror->get_line( ).
WRITE: 'line: ', i.
i = parseerror->get_column( ).
WRITE: 'column: ', i.
str = parseerror->get_reason( ).
WRITE: str.
index = index + 1.
ENDWHILE.
ENDIF.
ENDIF.
ENDFORM.
FORM get_xml_table CHANGING g_xml_table_size TYPE i
g_xml_table TYPE STANDARD TABLE.
DATA: l_len TYPE i,
l_content TYPE string,
l_str1 TYPE string,
l_itab TYPE TABLE OF string,
l_filename TYPE string.
l_filename = p_input.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = l_filename
filetype = 'BIN'
IMPORTING
filelength = g_xml_table_size
CHANGING
data_tab = g_xml_table
EXCEPTIONS
OTHERS = 19.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CLEAR l_str1.
LOOP AT g_xml_table INTO g_xml_line.
l_content = g_xml_line.
CONDENSE l_content.
CONCATENATE l_str1 l_content INTO l_str1.
ENDLOOP.
l_len = strlen( l_str1 ).
IF g_xml_table_size < l_len.
l_len = g_xml_table_size.
ENDIF.
l_str1 = l_str1+0(l_len).
SPLIT l_str1 AT c_break INTO TABLE l_itab.
WRITE: /.
WRITE: /' XML File'.
WRITE: /.
LOOP AT l_itab INTO l_str1.
DO.
REPLACE c_tab WITH space INTO l_str1.
IF sy-subrc <> 0.
EXIT.
ENDIF.
ENDDO.
WRITE: / l_str1.
ENDLOOP.
WRITE: /.
ENDFORM. FORM process_dom USING document TYPE REF TO if_ixml_document.
DATA: node TYPE REF TO if_ixml_node,
iterator TYPE REF TO if_ixml_node_iterator,
nodemap TYPE REF TO if_ixml_named_node_map,
attr TYPE REF TO if_ixml_node,
name TYPE string,
prefix TYPE string,
value TYPE string,
indent TYPE i,
count TYPE i,
index TYPE i.
node ?= document.
CHECK NOT node IS INITIAL.
ULINE.
WRITE: /.
WRITE: /' DOM-TREE'.
WRITE: /.
IF node IS INITIAL. EXIT. ENDIF.
iterator = node->create_iterator( ).
node = iterator->get_next( ).
WHILE NOT node IS INITIAL.
indent = node->get_height( ) * 2.
indent = indent + 20.
CASE node->get_type( ).
WHEN if_ixml_node=>co_node_element.
name = node->get_name( ).
nodemap = node->get_attributes( ).
WRITE: / 'ELEMENT :'.
WRITE: AT indent name COLOR COL_POSITIVE INVERSE.
IF NOT nodemap IS INITIAL.
count = nodemap->get_length( ).
DO count TIMES.
index = sy-index - 1.
attr = nodemap->get_item( index ).
name = attr->get_name( ).
value = attr->get_value( ).
WRITE: / 'ATTRIBUTE:'.
WRITE: AT indent name COLOR COL_HEADING INVERSE, '=',
value COLOR COL_TOTAL INVERSE.
ENDDO.
ENDIF.
WHEN if_ixml_node=>co_node_text OR
if_ixml_node=>co_node_cdata_section.
value = node->get_value( ).
WRITE: / 'VALUE :'.
WRITE: AT indent value COLOR COL_GROUP INVERSE.
ENDCASE.
node = iterator->get_next( ).
ENDWHILE.
ENDFORM. FORM get_file_name USING p_mask
CHANGING p_file LIKE rlgrap-filename.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
def_filename = p_file
def_path = 'C:\'
mask = p_mask
mode = '0'
title = ''
IMPORTING
filename = p_file
EXCEPTIONS
inv_winsys = 1
no_batch = 2
selection_cancel = 3
selection_error = 4
OTHERS = 5.
ENDFORM.