zoukankan      html  css  js  c++  java
  • 【ABAP系列】SAP ABAP解析XML的示例程序

    公众号: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
  • 相关阅读:
    thinkPHP入门之二
    thinkPHP入门
    斐波那契数列,冒泡排序,选择排序,数组去重
    jquery-懒加载插件
    本地存储之cookie
    javascript的快速排序法
    [luogu2165 AHOI2009] 飞行棋 (枚举)
    [luogu2576 SCOI2010] 幸运数字 (容斥原理)
    [luogu2587 ZJOI2008] 泡泡堂 (贪心)
    [luogu2602 ZJOI2010] 数字计数 (数位dp)
  • 原文地址:https://www.cnblogs.com/SAPmatinal/p/11181548.html
Copyright © 2011-2022 走看看