20.6. XML
if_ixml
if_ixml_document
if_ixml_node
if_ixml_element
if_ixml_istream
if_ixml_ostream
document、element、ATTRIBUTE、COMMENT、TEXT都属于 Node
20.6.1. 生成
<?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( ).
* 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?]
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. 解析
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( ).
WRITE: spaces, nodetype ,name,value .
ENDFORM.