ABAP解析XML的示例程序

本文提供了一个使用ABAP解析XML文件的示例程序。该程序通过创建iXML工厂、流工厂、解析器等组件来读取并解析指定的XML文件,并展示了如何处理可能发生的错误。此外,还演示了如何遍历解析后的DOM树结构。

点击进入:ABAP解析XML的示例程序

 

​
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
​

 

生成XML文件ABAP程序 REPORT zams_xml_dom_create . TYPE-POOLS: ixml. CLASS cl_ixml DEFINITION LOAD. TYPES: BEGIN OF xml_line, data(256) TYPE x, END OF xml_line. DATA: l_ixml TYPE REF TO if_ixml, l_streamfactory TYPE REF TO if_ixml_stream_factory, l_ostream TYPE REF TO if_ixml_ostream, l_renderer TYPE REF TO if_ixml_renderer, l_document TYPE REF TO if_ixml_document. DATA:l_element_ArchiveBatch TYPE REF TO if_ixml_element, l_element_BatchNumber TYPE REF TO if_ixml_element, l_element_TotalFiles TYPE REF TO if_ixml_element, l_element_TotalVolumes TYPE REF TO if_ixml_element, l_element_TotalPieces TYPE REF TO if_ixml_element, l_element_Entries TYPE REF TO if_ixml_element, l_element_Entry TYPE REF TO if_ixml_element, l_element_RecordsCombiningType TYPE REF TO if_ixml_element, l_element_FilePath TYPE REF TO if_ixml_element, l_element_SourceFileName TYPE REF TO if_ixml_element, l_element_ClassificationCode TYPE REF TO if_ixml_element, l_element_ElectronicRecordCode TYPE REF TO if_ixml_element, l_value TYPE string, l_name type string. DATA: l_xml_table TYPE TABLE OF xml_line, l_xml_size TYPE i, l_rc TYPE i. START-OF-SELECTION. *Creating a ixml factory l_ixml = cl_ixml=>create( ). *Creating the dom object model l_document = l_ixml->create_document( ). *Fill root node with value ArchiveBatch l_element_ArchiveBatch = l_document->create_simple_element( name = 'ArchiveBatch' parent = l_document ). * clear l_value. * l_value = '"http://www.w3.org/2001/XMLSchema-instance"'. * l_rc = l_element_ArchiveBatch->set_attribute( name = 'xmlns: *xsi' * value = l_value ). * * clear l_value. * concatenate '"D:\dev\vs\projects\AMS\DotNet\Sinopec.Ams.' * 'Integration\bin\Debug\config\AmsIntegration.xsd"' * into l_value. * l_name = 'xsi:noNamespaceSchemaLocation'. * l_rc = l_element_ArchiveBatch->set_attribute( name = l_name *value = l_value ). *BatchNumber l_element_BatchNumber = l_document->create_simple_element( name = 'BatchNumber' value = '20100609001' parent = l_element_ArchiveBatch ). *TotalFiles l_element_TotalFiles = l_document->create_simple_element( name = 'TotalFiles' value = '5' parent = l_element_ArchiveBatch ). *TotalVolumes l_element_TotalVolumes = l_document->create_simple_element( name = 'TotalVolumes' value = '3' parent = l_element_ArchiveBatch ). *TotalPieces l_element_TotalPieces = l_document->create_simple_element( name = 'TotalPieces' value = '5' parent = l_element_ArchiveBatch ). *Entries l_element_Entries = l_document->create_simple_element( name = 'Entries' parent = l_element_ArchiveBatch ). *Entry1 l_element_Entry = l_document->create_simple_element( name = 'Entry' parent = l_element_Entries ). *Entry1下面的子项 *RecordsCombiningType l_element_RecordsCombiningType = l_document->create_simple_element( name = 'RecordsCombiningType' value = 'Volume' parent = l_element_Entry ). *FilePath l_element_FilePath = l_document->create_simple_element( name = 'FilePath' value = '全宗001/目录001/案卷001/档案一.docx' parent = l_element_Entry ). *SourceFileName l_element_SourceFileName = l_document->create_simple_element( name = 'SourceFileName' value = '档案一' parent = l_element_Entry ). *ClassificationCode l_element_ClassificationCode = l_document->create_simple_element( name = 'ClassificationCode' value = 'wenshu' parent = l_element_Entry ). *ElectronicRecordCode l_element_ElectronicRecordCode = l_document->create_simple_element( name = 'ElectronicRecordCode' value = 'BJSH-001' parent = l_element_Entry ). *Entry1 * Creating a stream factory l_streamfactory = l_ixml->create_stream_factory( ). * Connect internal XML table to stream factory l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ). * Rendering the document l_renderer = l_ixml->create_renderer( ostream = l_ostream document = l_document ). l_rc = l_renderer->render( ). * Saving the XML document l_xml_size = l_ostream->get_num_written_raw( ). CALL METHOD cl_gui_frontend_services=>gui_download EXPORTING bin_filesize = l_xml_size filename = 'c:\temp\metas.xml' filetype = 'BIN' CHANGING data_tab = l_xml_table EXCEPTIONS OTHERS = 24. IF sy-subrc 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值