[SAP ABAP开发技术总结]ABAP读写、解析XML文件

时间:2021-08-02 03:18:06

 

20.6.     XML

if_ixml

if_ixml_document
if_ixml_
node

if_ixml_element

if_ixml_istream

if_ixml_ostream

documentelementATTRIBUTECOMMENTTEXT都属于 Node

20.6.1.           生成

[SAP ABAP开发技术总结]ABAP读写、解析XML文件

<?xml version="1.0"?>

<flow BAPI="ZBAPI_MM_RK_AFTER_APP" DES="广深公司-采购订单" KEY="gsgs-cgdd"><customform><fd n="flight"><V>110000</V></fd><fd n="flight"><V>090000</V></fd></customform></flow>

 

TYPE-POOLS: ixml,abap.
TYPES: BEGIN OF xml_line,
       
data(512) TYPE x,"这里的长度设置不会影响输出结果,设置成1都可以
      
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_flights TYPE REF TO if_ixml_element,
      l_element_airline
TYPE REF TO if_ixml_element,
      l_element_flight 
TYPE REF TO if_ixml_element,
      l_element_dummy  
TYPE REF TO if_ixml_element,
      l_value          
TYPE string.
DATA: l_xml_table       TYPE TABLE OF xml_line WITH HEADER LINE,
      l_xml_size       
TYPE i,
      l_rc             
TYPE i.
DATA: lt_spfli          TYPE TABLE OF spfli.
DATA: l_spfli           TYPE spfli.

START-OF-SELECTION.
 
SELECT * FROM spfli INTO TABLE lt_spfli UP TO 2 ROWS.
 
SORT lt_spfli BY carrid.
* 生成XML数据
 
LOOP AT lt_spfli INTO l_spfli.
   
AT FIRST.
*       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 flow
      l_element_flights 
= l_document->create_simple_element(
                  name
= 'flow'
                  parent
= l_document ).
      l_rc
= l_element_flights->set_attribute( name = 'KEY' value = 'gsgs-cgdd' ).
      l_rc
= l_element_flights->set_attribute( name = 'DES' value = '广深公司-采购订单').
      l_rc
= l_element_flights->set_attribute( name = 'BAPI' value ='ZBAPI_MM_RK_AFTER_APP' ).
      l_element_airline 
= l_document
->create_simple_element(
                  name
= 'customform'
                  parent
= l_element_flights  ). "parent为父节点
   
ENDAT.
   
AT NEW connid.
      l_element_flight 
= l_document->create_simple_element(
                  name
= 'fd'
                  parent
= l_element_airline  ).
     
"l_value = l_spfli-connid.
      l_rc
= l_element_flight
->set_attribute( name = 'n' value = 'flight' ).
   
ENDAT.
    l_value
= l_spfli-deptime.
    l_element_dummy 
= l_document->create_simple_element(
                name
= 'V'
               
value = l_value
                parent
= l_element_flight ).

 
ENDLOOP.
*   Creating a stream factory
  l_streamfactory
= l_ixml->create_stream_factory( ).[stri:m]
*   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    [?rend?] [SAP ABAP开发技术总结]ABAP读写、解析XML文件
                                        document
= l_document )." l_document为根节点
  l_rc
= l_renderer->render( )."注:执行此句后, l_xml_table内表里才会有数据
  l_xml_size
= l_ostream->get_num_written_raw( )."取得XML数据大小
*************************************************************
**--xml数据导出到本地
* call method cl_gui_frontend_services=>gui_download
*   exporting
*     bin_filesize = l_xml_size
*     filename     = 'd:\flights.xml'
*     filetype     = 'BIN'
*   changing
*     data_tab     = l_xml_table[].
************************************************************
****************************************************
**--XML数据导入到内表
*  DATA xmldata TYPE xstring .
*  DATA: result_xml TYPE STANDARD TABLE OF smum_xmltb .
*  DATA: return TYPE STANDARD TABLE OF bapiret2 .
*  DATA: wa_xml TYPE smum_xmltb.
*  "如果需要上载XML可以用一下方法
*  CALL FUNCTION 'GUI_UPLOAD'
*    EXPORTING
*      filename   = 'd:\flights.xml'
*      filetype   = 'BIN'
*    IMPORTING
*      filelength = l_xml_size
*    TABLES
*      data_tab   = l_xml_table.
*  "将二进制内表转换(拼接)成一个二进制串
*  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
*    EXPORTING
*      input_length = l_xml_size
*    IMPORTING
*      buffer       = xmldata
*    TABLES
*      binary_tab   = l_xml_table.
*  CALL FUNCTION 'SMUM_XML_PARSE'"解析
*    EXPORTING
*      xml_input = xmldata
*    TABLES
*      xml_table = result_xml
*      return    = return.
*  LOOP AT result_xml INTO wa_xml .
*    WRITE: / wa_xml-hier,wa_xml-type,wa_xml-cname,wa_xml-cvalue.
*  ENDLOOP.
************************************************
**************************************************
**XML转换成字符串
*  DATA: w_string TYPE xstring.
*  DATA ls_xml TYPE string.
*  FIELD-SYMBOLS: <fs> TYPE string.
*  CALL FUNCTION 'SDIXML_DOM_TO_XML'
*    EXPORTING
*      document      = l_document
*    IMPORTING
*      xml_as_string = w_string
*      size          = l_xml_size
*    TABLES
*      xml_as_table  = l_xml_table.
*
*  DATA: convin TYPE REF TO cl_abap_conv_in_ce.
*  "创建解码对象
*  convin = cl_abap_conv_in_ce=>create( input = w_string ).
*  DATA: str TYPE string.
*  CALL METHOD convin->read
*    IMPORTING
*      data = ls_xml.
*  WRITE: / ls_xml.
* 将一个二进制串分割存储到二进制内表中
*  call function 'SCMS_XSTRING_TO_BINARY'
*    exporting
*      BUFFER        = W_STRING
*    importing
*      OUTPUT_LENGTH = L_XML_SIZE
*    tables
*      BINARY_TAB    = L_XML_TABLE.
 
"将二进制内表转换(拼接)成一个字符串
*  CALL FUNCTION 'SCMS_BINARY_TO_STRING'
*    EXPORTING
*      input_length = l_xml_size
*    IMPORTING
*      text_buffer  = ls_xml
*    TABLES
*      binary_tab   = l_xml_table.
*  WRITE: / ls_xml.
****************************************************************

20.6.2.           解析


[SAP ABAP开发技术总结]ABAP读写、解析XML文件

[SAP ABAP开发技术总结]ABAP读写、解析XML文件

TYPE-POOLS: ixml.
DATA: ixml          TYPE REF TO if_ixml,
      document     
TYPE REF TO if_ixml_document,
      streamfactory
TYPE REF TO if_ixml_stream_factory,
      istream      
TYPE REF TO if_ixml_istream,
      parser       
TYPE REF TO if_ixml_parser,
      node         
TYPE REF TO if_ixml_node,
      string        
TYPE string,
     
count          TYPE i,
     
index          TYPE i,
      totalsize     
TYPE i .
TYPES: BEGIN OF xml_line,
       
data(256) TYPE x,
     
END OF xml_line.
DATA: xml_table TYPE TABLE OF xml_line.
START-OF-SELECTION.
 
CALL FUNCTION 'GUI_UPLOAD'
   
EXPORTING
      filename  
= 'd:\flights.xml'
      filetype  
= 'BIN'
   
IMPORTING
      filelength
= totalsize
   
TABLES

      data_tab  
= xml_table
   
EXCEPTIONS

     
OTHERS     = 11.
 
IF sy-subrc <> 0.
   
EXIT.
 
ENDIF.

  ixml
= cl_ixml=>create( ).
  document
= ixml->create_document( ).
  streamfactory
= ixml->create_stream_factory( ).
  istream
= streamfactory->create_istream_itable( table = xml_table
                                                   
size  = totalsize ).

  parser
= ixml->create_parser( stream_factory = streamfactory
                                  istream       
=
istream
                                  document      
= document ).

 
IF parser->parse( ) NE 0.
   
IF parser->num_errors( ) NE 0.
     
count = parser->num_errors( ).
     
WRITE: count, ' parse errors have occured:'.
     
DATA: pparseerror TYPE REF TO if_ixml_parse_error,
           
i TYPE i.
     
index = 0.
     
WHILE index < count.
        pparseerror
= parser->get_error( index = index ).
       
i = pparseerror->get_line( ).
       
WRITE: 'line: ', i.
       
i = pparseerror->get_column( ).
       
WRITE: 'column: ', i.
        string
= pparseerror->get_reason( ).
       
WRITE: string.
       
index = index + 1.
     
ENDWHILE.
   
ENDIF.
 
ENDIF.

 
CALL METHOD istream->close( ).
 
CLEAR istream.
  node
= document.
 
PERFORM print_node USING node 0.

FORM print_node  USING p_node TYPE REF TO if_ixml_node deep TYPE i.
 
DATA: nodetype TYPE i,
        attrslen
TYPE i,
        attrs
TYPE REF TO if_ixml_named_node_map,
        attr
TYPE REF TO if_ixml_node.
  nodetype
= p_node->get_type( ).
  
CASE p_node->get_type( ).
   
WHEN if_ixml_node=>co_node_element."这里只处理元素节点
     
WRITE: /.
     
PERFORM printnodeinfo USING '元素' deep p_node.
      attrs
= p_node
->get_attributes( ).
      attrslen
= attrs->get_length( ).
     
DO attrslen TIMES.
        attr
= attrs->get_item( sy-index - 1 ).
       
PERFORM printnodeinfo USING '属性' deep attr.
     
ENDDO.
     
"WHEN if_ixml_node=>co_node_text.
     
"PERFORM printnodeinfo USING '文本' deep p_node.
 
ENDCASE.
 
DATA: childs TYPE REF TO if_ixml_node_list,
        child
TYPE REF TO if_ixml_node,
        childslen
TYPE i.
  childs
= p_node
->get_children( ).
  childslen
childs->get_length( ).
 
DATA: deep2 TYPE i.
  deep2
deep + 1.
 
DO childslen  TIMES.
    child
childs->get_item( sy-index - 1 ).
   
PERFORM print_node USING child deep2.
 
ENDDO.
ENDFORM.

FORM printnodeinfo USING nodetype TYPE string deep TYPE i node TYPE REF TO if_ixml_node.
 
DATA: name TYPE string,
       
value TYPE string,
        spaces
TYPE string.
 
DO deep TIMES.
    spaces
= spaces && ` `.
 
ENDDO.
  name
= node->get_name( ).
 
value = node->get_value( ).
 
WRITEspaces, nodetype ,name,value .
ENDFORM.