公众号:matinal
本文作者:matinal
前言部分
大家可以关注我的公众号,公众号里的排版更好,阅读更舒适。
正文部分
TYPE-POOLS: IXML. TYPES: BEGIN OF T_XML_LINE, DATA(256) TYPE X, END OF T_XML_LINE. DATA: L_IXML TYPE REF TO IF_IXML, L_STREAMFACTORY TYPE REF TO IF_IXML_STREAM_FACTORY, L_PARSER TYPE REF TO IF_IXML_PARSER, L_ISTREAM TYPE REF TO IF_IXML_ISTREAM, L_DOCUMENT TYPE REF TO IF_IXML_DOCUMENT, L_NODE TYPE REF TO IF_IXML_NODE, L_XMLDATA TYPE STRING. DATA: L_ELEM TYPE REF TO IF_IXML_ELEMENT, L_ROOT_NODE TYPE REF TO IF_IXML_NODE, L_NEXT_NODE TYPE REF TO IF_IXML_NODE, L_NAME TYPE STRING, L_ITERATOR TYPE REF TO IF_IXML_NODE_ITERATOR. DATA: L_XML_TABLE TYPE TABLE OF T_XML_LINE, L_XML_LINE TYPE T_XML_LINE, L_XML_TABLE_SIZE TYPE I. DATA: L_FILENAME TYPE STRING. PARAMETERS: PA_FILE TYPE CHAR1024 DEFAULT 'D:FILE.XML'. *Validation of XML file: Only DTD included in xml document is supported PARAMETERS: PA_VAL TYPE CHAR1 AS CHECKBOX. START-OF-SELECTION. * Creating the main iXML factory L_IXML = CL_IXML=>CREATE( ). * Creating a stream factory L_STREAMFACTORY = L_IXML->CREATE_STREAM_FACTORY( ). PERFORM GET_XML_TABLE CHANGING L_XML_TABLE_SIZE L_XML_TABLE. * wrap the table containing the file into a stream L_ISTREAM = L_STREAMFACTORY->CREATE_ISTREAM_ITABLE( TABLE = L_XML_TABLE SIZE = L_XML_TABLE_SIZE ). * Creating a document L_DOCUMENT = L_IXML->CREATE_DOCUMENT( ). * Create a Parser L_PARSER = L_IXML->CREATE_PARSER( STREAM_FACTORY = L_STREAMFACTORY ISTREAM = L_ISTREAM DOCUMENT = L_DOCUMENT ). * Validate a document IF PA_VAL EQ 'X'. L_PARSER->SET_VALIDATING( MODE = IF_IXML_PARSER=>CO_VALIDATE ). ENDIF. * Parse the stream DATA: PARSEERROR TYPE REF TO IF_IXML_PARSE_ERROR, STR TYPE STRING, I TYPE I, COUNT TYPE I, INDEX TYPE I. IF L_PARSER->PARSE( ) NE 0. IF L_PARSER->NUM_ERRORS( ) NE 0. COUNT = L_PARSER->NUM_ERRORS( ). WRITE: COUNT, ' parse errors have occured:'. INDEX = 0. WHILE INDEX < COUNT. PARSEERROR = L_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. * Process the document IF L_PARSER->IS_DOM_GENERATING( ) EQ 'X'. PERFORM PROCESS_DOM USING L_DOCUMENT. ENDIF. *&---------------------------------------------------------------------* *& Form GET_XML_TABLE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->L_XML_TABLE_SIZE text * -->L_XML_TABLE text *----------------------------------------------------------------------* FORM GET_XML_TABLE CHANGING L_XML_TABLE_SIZE TYPE I L_XML_TABLE TYPE STANDARD TABLE. * Local variable declaration DATA: L_LEN TYPE I, L_LEN2 TYPE I, L_TAB TYPE TSFIXML, L_CONTENT TYPE STRING, L_STR1 TYPE STRING, C_CONV TYPE REF TO CL_ABAP_CONV_IN_CE, L_ITAB TYPE TABLE OF STRING. L_FILENAME = PA_FILE. * upload a file from the client's workstation CALL METHOD CL_GUI_FRONTEND_SERVICES=>GUI_UPLOAD EXPORTING FILENAME = L_FILENAME FILETYPE = 'BIN' IMPORTING FILELENGTH = L_XML_TABLE_SIZE CHANGING DATA_TAB = L_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. * Writing the XML document to the screen CLEAR L_STR1. LOOP AT L_XML_TABLE INTO L_XML_LINE. C_CONV = CL_ABAP_CONV_IN_CE=>CREATE( INPUT = L_XML_LINE-DATA REPLACEMENT = SPACE ). C_CONV->READ( IMPORTING DATA = L_CONTENT LEN = L_LEN ). CONCATENATE L_STR1 L_CONTENT INTO L_STR1. ENDLOOP. L_STR1 = L_STR1+0(L_XML_TABLE_SIZE). SPLIT L_STR1 AT CL_ABAP_CHAR_UTILITIES=>CR_LF INTO TABLE L_ITAB. WRITE: /. WRITE: /' XML File'. WRITE: /. LOOP AT L_ITAB INTO L_STR1. REPLACE ALL OCCURRENCES OF CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB IN L_STR1 WITH SPACE. WRITE: / L_STR1. ENDLOOP. WRITE: /. ENDFORM. "get_xml_table *&---------------------------------------------------------------------* *& Form PROCESS_DOM *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * -->DOCUMENT text *----------------------------------------------------------------------* 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. * create a node iterator ITERATOR = NODE->CREATE_ITERATOR( ). * get current node NODE = ITERATOR->GET_NEXT( ). * loop over all nodes WHILE NOT NODE IS INITIAL. INDENT = NODE->GET_HEIGHT( ) * 2. INDENT = INDENT + 20. CASE NODE->GET_TYPE( ). WHEN IF_IXML_NODE=>CO_NODE_ELEMENT. * element node NAME = NODE->GET_NAME( ). NODEMAP = NODE->GET_ATTRIBUTES( ). WRITE: / 'ELEMENT :'. WRITE: AT INDENT NAME COLOR COL_POSITIVE INVERSE. IF NOT NODEMAP IS INITIAL. * attributes COUNT = NODEMAP->GET_LENGTH( ). DO COUNT TIMES. INDEX = SY-INDEX - 1. ATTR = NODEMAP->GET_ITEM( INDEX ). NAME = ATTR->GET_NAME( ). PREFIX = ATTR->GET_NAMESPACE_PREFIX( ). 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. * text node VALUE = NODE->GET_VALUE( ). WRITE: / 'VALUE :'. WRITE: AT INDENT VALUE COLOR COL_GROUP INVERSE. ENDCASE. * advance to next node NODE = ITERATOR->GET_NEXT( ). ENDWHILE. ENDFORM. "process_dom