写接口用到XML,但又不想每次写STRANS,在网页和github都没找到合适的(可能也有但是我没找到)
参考:https://blogs.sap.com/2014/08/01/abap-to-xml-and-vice-versa/
这个人写的ABAP2XML可以用,但是有个缺点,当节点是表类型的时候,会同时定义一个table节点<sflight>和structure节点<sflight>。所以我对它的代码改了一下,如果有BUG或者问题,还请评论告诉我
这里有个问题,虽然mo_document->set_encoding设置的是 'UTF-8',得到的ev_content都是'UTF-16',
但是把xstring或者binary下载到本地.xml文件,显示的是对的'UTF-8'。所以我理解为if_ixml_element生成的XML的STRING类型默认显示'UTF-16',就给REPLACE替换了一下。
完整代码如下,SE24粘贴即可
1 class ZCL_XML_UTIL definition 2 public 3 create public . 4 5 public section. 6 7 *”* public components of class ZCL_XML_UTIL 8 *”* do not include other source files here!!! 9 methods CONSTRUCTOR . 10 methods ABAP_TO_XML 11 importing 12 !IM_DATA type ANY 13 exporting 14 !EX_CONTENT type XSTRING 15 !EV_CONTENT type STRING . 16 methods XML_TO_ABAP 17 importing 18 !IM_CONTENT type STRING optional 19 !IM_CONTENT_X type XSTRING optional 20 exporting 21 !EX_DATA type ANY . 22 protected section. 23 *”* protected components of class ZCL_XML_UTIL 24 *”* do not include other source files here!!! 25 26 data MO_IXML type ref to IF_IXML . 27 data MO_DOCUMENT type ref to IF_IXML_DOCUMENT . 28 private section. 29 30 *”* private components of class ZCL_XML_UTIL 31 *”* do not include other source files here!!! 32 methods PROCESS 33 importing 34 !IM_NODE type ref to IF_IXML_NODE 35 !IM_NAME type STRING 36 !IM_DATA type ANY 37 exceptions 38 TYPE_ERROR . 39 methods CREATE_ELEMENT 40 importing 41 !IM_NAME type STRING 42 !IM_VALUE type STRING optional 43 returning 44 value(RE_ELEMENT) type ref to IF_IXML_ELEMENT . 45 methods TRAVERSE 46 importing 47 !IM_CURRENT_NODE type ref to IF_IXML_NODE 48 changing 49 !CH_DATA type ANY 50 exceptions 51 TYPE_NOT_FOUND . 52 class-methods AS_STRING 53 importing 54 !IM_DATA type ANY 55 returning 56 value(RE_DATA_STRING) type STRING . 57 ENDCLASS. 58 59 60 61 CLASS ZCL_XML_UTIL IMPLEMENTATION. 62 63 64 * <SIGNATURE>---------------------------------------------------------------------------------------+ 65 * | Instance Public Method ZCL_XML_UTIL->ABAP_TO_XML 66 * +-------------------------------------------------------------------------------------------------+ 67 * | [--->] IM_DATA TYPE ANY 68 * | [<---] EX_CONTENT TYPE XSTRING 69 * | [<---] EV_CONTENT TYPE STRING 70 * +--------------------------------------------------------------------------------------</SIGNATURE> 71 METHOD abap_to_xml. 72 73 CLEAR : ex_content. 74 75 * create .xml document 76 mo_document = mo_ixml->create_document( ). 77 78 * set encoding to UTF-8 (Unicode Transformation Format) 79 * 8-bit variable-width encoding maximizes compatibility with ASCII 80 mo_document->set_encoding( mo_ixml->create_encoding( 81 byte_order = 0 82 character_set = 'UTF-8' ) ). 83 84 85 * use mo_document as root 86 IF NOT im_data IS INITIAL. 87 process( im_node = mo_document 88 im_name = 'docinfo' 89 im_data = im_data ). 90 ENDIF. 91 92 93 * render .xml document with output stream 94 *--------------------------------------------------------------------* 95 *xstring 96 mo_document->render( 97 ostream = mo_ixml->create_stream_factory( )->create_ostream_xstring( 98 string = ex_content ) ). 99 100 *--------------------------------------------------------------------* 101 *string 102 mo_document->render( 103 ostream = mo_ixml->create_stream_factory( )->create_ostream_cstring( 104 string = ev_content ) ). 105 REPLACE 'encoding="utf-16"' WITH 'encoding="utf-8"' INTO ev_content. "实质以create_encoding为准 106 107 *--------------------------------------------------------------------* 108 *itable 109 * TYPES: BEGIN OF xml_line, 110 * data(256) TYPE x, "这里的长度设置不会影响输出结果 111 * END OF xml_line. 112 * DATA:et_content TYPE TABLE OF xml_line. 113 * data(l_ostream) = mo_ixml->create_stream_factory( )->create_ostream_itable( 114 * table = et_content ). 115 * mo_document->render( l_ostream ). 116 * data(xml_size) = l_ostream->get_num_written_raw( )."取得XML数据大小 117 118 119 FREE : mo_document. 120 ENDMETHOD. 121 122 123 * <SIGNATURE>---------------------------------------------------------------------------------------+ 124 * | Static Private Method ZCL_XML_UTIL=>AS_STRING 125 * +-------------------------------------------------------------------------------------------------+ 126 * | [--->] IM_DATA TYPE ANY 127 * | [<-()] RE_DATA_STRING TYPE STRING 128 * +--------------------------------------------------------------------------------------</SIGNATURE> 129 METHOD AS_STRING. 130 131 MOVE im_data TO re_data_string. 132 133 ENDMETHOD. 134 135 136 * <SIGNATURE>---------------------------------------------------------------------------------------+ 137 * | Instance Public Method ZCL_XML_UTIL->CONSTRUCTOR 138 * +-------------------------------------------------------------------------------------------------+ 139 * +--------------------------------------------------------------------------------------</SIGNATURE> 140 METHOD CONSTRUCTOR. 141 142 * get iXML library instance 143 mo_ixml = cl_ixml=>create( ). 144 145 ENDMETHOD. 146 147 148 * <SIGNATURE>---------------------------------------------------------------------------------------+ 149 * | Instance Private Method ZCL_XML_UTIL->CREATE_ELEMENT 150 * +-------------------------------------------------------------------------------------------------+ 151 * | [--->] IM_NAME TYPE STRING 152 * | [--->] IM_VALUE TYPE STRING(optional) 153 * | [<-()] RE_ELEMENT TYPE REF TO IF_IXML_ELEMENT 154 * +--------------------------------------------------------------------------------------</SIGNATURE> 155 METHOD CREATE_ELEMENT. 156 157 DATA : 158 lv_name TYPE string VALUE IS INITIAL. 159 160 * element names look cooler in lower case