XML 与ABAP对象转换

sap与外部系统通过接口交互时,数据的传递通常有XML, JSON等格式,此处介绍XML与ABAP结构、内表互转的两种常用方法。

A.一种是通过类cl_xml_document 解析转换XML字符串,该方式优点是代码实现方式简单,只需定义与XML中节点及字段对应的结构即可,缺点是只支持转换XML中大写的字段名 ,节点名,详见一, 二 ,三的函数方法

B.另一种是通过事务代码STRANS的转换方法实现(EPIC的银行报文转换常用该方法实现),该方法优点是支持大小写自定义的XML节点及字段名,缺点是需要手工编辑XML的格式,相比于A方式较繁琐。

一、 ABAP结构、内表转XML

YMCAFG_DATA2XML

复制代码
FUNCTION YMCAFG_DATA2XML.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(I_DATA)
*"     REFERENCE(NO_INIT_ELEMENT) TYPE  CHAR1 DEFAULT ''
*"  EXPORTING
*"     REFERENCE(E_XML)
*"     REFERENCE(ES_RETMESS) TYPE  YMSRETMESS
*"----------------------------------------------------------------------
  DATA: LC_XML TYPE REF TO CL_XML_DOCUMENT.

*-->XML封装

 根据输入的结构或内表构建XML字符串节点,及数据的填充
 CREATE OBJECT LC_XML.
  CALL METHOD LC_XML->SET_DATA
    EXPORTING
      DATAOBJECT = I_DATA
    RECEIVING
      RETCODE    = ES_RETMESS-RC.
  IF ES_RETMESS-RC <> 0.
    MESSAGE S007(YMCA) INTO ES_RETMESS-MESSAGE.
    RETURN.
  ENDIF.


输出XML格式的字符串数据
  CALL METHOD LC_XML->RENDER_2_STRING
    EXPORTING
      PRETTY_PRINT = 'X'
    IMPORTING
      RETCODE      = ES_RETMESS-RC
      STREAM       = E_XML.
  IF ES_RETMESS-RC <> 0.
    MESSAGE S007(YMCA) INTO ES_RETMESS-MESSAGE.
    RETURN.
  ENDIF.

ENDFUNCTION.
View Code
复制代码

二、XMLABAP结构

YMCAFG_XML2STRUC

复制代码
FUNCTION YMCAFG_XML2STRUC.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(INPUT) TYPE  STRING
*"  EXPORTING
*"     VALUE(ES_RETMESS) TYPE  YMSRETMESS
*"  CHANGING
*"     VALUE(CS_DATA)
*"----------------------------------------------------------------------
  DATA: LC_XML     TYPE REF TO CL_XML_DOCUMENT,
        LV_RETCODE TYPE        SYSUBRC.

  IF INPUT IS INITIAL.
    ES_RETMESS-RC = 0.
    RETURN.
  ENDIF.

***>解析XML
  CREATE OBJECT LC_XML.
  CALL METHOD LC_XML->PARSE_STRING
    EXPORTING
      STREAM  = INPUT
    RECEIVING
      RETCODE = ES_RETMESS-RC.
  IF ES_RETMESS-RC <> 0.
    MESSAGE S055(YMCA) INTO ES_RETMESS-MESSAGE.     "XML解析失败
    RETURN.
  ENDIF.

根据接收的结构去匹配XML字符串中各个节点及字段
  CALL METHOD LC_XML->GET_DATA
    IMPORTING
      RETCODE    = LV_RETCODE
    CHANGING
      DATAOBJECT = CS_DATA.

*  IF cs_data IS INITIAL.
  IF LV_RETCODE IS NOT INITIAL.
    ES_RETMESS-RC = 4.
    MESSAGE S055(YMCA) INTO ES_RETMESS-MESSAGE.
  ENDIF.


ENDFUNCTION.
View Code
复制代码

三、XMLABAP内表

YMCAFG_XML2DATA

复制代码
FUNCTION ymcafg_xml2data.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(INPUT) TYPE  STRING
*"  EXPORTING
*"     VALUE(ES_RETMESS) TYPE  YMSRETMESS
*"  TABLES
*"      T_DATA
*"----------------------------------------------------------------------
  DATA: lc_xml TYPE REF TO cl_xml_document.

  IF input IS INITIAL.
    es_retmess-rc = 0.
    RETURN.
  ENDIF.

***>解析XML
  CREATE OBJECT lc_xml.
  CALL METHOD lc_xml->parse_string
    EXPORTING
      stream  = input
    RECEIVING
      retcode = es_retmess-rc.
  IF es_retmess-rc <> 0.
    MESSAGE s006(ymca) INTO es_retmess-message.     "XML解析失败
    RETURN.
  ENDIF.
根据接收的内表结构匹配获取XML中节点及字段
  CALL METHOD lc_xml->get_data
    CHANGING
      dataobject = t_data[].


ENDFUNCTION.
View Code
复制代码

四、STRANS转换XML

1.ABAP结构或内表对象转换为XML 

           <trnid>
          <xsl:value-of select="TRNID"/>
        </trnid>

以该格式说明, <xsl:value-of select="TRNID"/>中的 TRNID是被转换的字段名,
<trnid>   </trnid> 是转换后的XML目标字段名

复制代码
XML报文头固定格式设置:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:asx="http://www.sap.com/abapxml" exclude-result-prefixes="asx" version="1.0">

  <xsl:strip-space elements="*"/>
  <xsl:output encoding="GBK" indent="no" omit-xml-declaration="no"/>
  <xsl:template match="/asx:abap/asx:values/PARAMETERS">

 以下是根据每个业务需求定义的XML报文的结构

    <bocb2e>
      <xsl:attribute name="locale">zh_CN</xsl:attribute>
      <xsl:attribute name="security">true</xsl:attribute>
      <xsl:attribute name="version">120</xsl:attribute>
      <head>
        <termid>
          <xsl:value-of select="TERMID"/>
        </termid>
        <trnid>
          <xsl:value-of select="TRNID"/>
        </trnid>
        <custid>
          <xsl:value-of select="CUSTID"/>
        </custid>
        <cusopr>
          <xsl:value-of select="CUSOPR"/>
        </cusopr>
        <trncod>
          <xsl:value-of select="TRNCOD"/>
        </trncod>
        <token>
          <xsl:value-of select="TOKEN"/>
        </token>
      </head>
      <trans>
        <trn-b2e0078-rq>
          <ceitinfo>
            <xsl:value-of select="ZCEITINFO"/>
          </ceitinfo>
          <transtype>
            <xsl:value-of select="ZTRANSTYPE"/>
          </transtype>
          <b2e0078-rq>
            <insid>
              <xsl:value-of select="ZINSID"/>
            </insid>
            <fractn>
              <fribkn>
                <xsl:value-of select="ZFRIBKN"/>
              </fribkn>
              <actacn>
                <xsl:value-of select="ZACTACN"/>
              </actacn>
              <actnam>
                <xsl:value-of select="ZACTNAM"/>
              </actnam>
            </fractn>
            <telephone>
              <xsl:value-of select="ZTELEPHONE"/>
            </telephone>
            <pybcur>
              <xsl:value-of select="ZPYBCUR"/>
            </pybcur>
            <pybamt>
              <xsl:value-of select="ZPYBAMT"/>
            </pybamt>
            <pybnum>
              <xsl:value-of select="ZPYBNUM"/>
            </pybnum>
            <crdtyp>
              <xsl:value-of select="ZCRDTYP"/>
            </crdtyp>
            <furinfo>
              <xsl:value-of select="ZFURINFO"/>
            </furinfo>
            <useinf>
              <xsl:value-of select="ZUSEINF"/>
            </useinf>
            <trfdate>
              <xsl:value-of select="ZTRFDATE"/>
            </trfdate>
            <!--            <detail>-->
            <xsl:for-each select="ROW/*">
              <detail>
                <toibkn>
                  <xsl:value-of select="ZTOIBKN"/>
                </toibkn>
                <tobank>
                  <xsl:value-of select="ZTOBANK"/>
                </tobank>
                <toactn>
                  <xsl:value-of select="ZTOACTN"/>
                </toactn>
                <pydcur>
                  <xsl:value-of select="ZPYDCUR"/>
                </pydcur>
                <pydamt>
                  <xsl:value-of select="ZPYDAMT"/>
                </pydamt>
                <toname>
                  <xsl:value-of select="ZTONAME"/>
                </toname>
                <toidtp>
                  <xsl:value-of select="ZTOIDTP"/>
                </toidtp>
                <toidet>
                  <xsl:value-of select="ZTOIDET"/>
                </toidet>
                <furinfo>
                  <xsl:value-of select="ZFURINFO"/>
                </furinfo>
                <purpose>
                  <xsl:value-of select="ZPURPOSE"/>
                </purpose>
                <reserve1>
                  <xsl:value-of select="ZRESERVE1"/>
                </reserve1>
                <reserve2>
                  <xsl:value-of select="ZRESERVE2"/>
                </reserve2>
                <reserve3>
                  <xsl:value-of select="ZRESERVE3"/>
                </reserve3>
                <reserve4>
                  <xsl:value-of select="ZRESERVE4"/>
                </reserve4>
              </detail>
            </xsl:for-each>
            <!--            </detail>-->
          </b2e0078-rq>
        </trn-b2e0078-rq>
      </trans>
    </bocb2e>
  </xsl:template>
</xsl:transform>
View Code
复制代码

2.XML报文转换为ABAP结构或内表对象

复制代码
XML报文头固定格式部分:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:template match="/">
    <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
      <asx:values>
XML报文结构自定义部分
        <RESPONSE>
          <xsl:choose>
            <xsl:when test="bocb2e/head/trncod = 'b2eerror'">
              <INFO>
                <RSPCOD>
                  <xsl:value-of select="bocb2e/trans/trn-b2eerror-rs/status/rspcod"/>
                </RSPCOD>
                <RSPMSG>
                  <xsl:value-of select="bocb2e/trans/trn-b2eerror-rs/status/rspmsg"/>
                </RSPMSG>
              </INFO>
            </xsl:when>

            <xsl:otherwise>
              <INFO>
                <RSPCOD>
                  <xsl:value-of select="bocb2e/trans/trn-b2e0078-rs/status/rspcod"/>
                </RSPCOD>
                <RSPMSG>
                  <xsl:value-of select="bocb2e/trans/trn-b2e0078-rs/status/rspmsg"/>
                </RSPMSG>
              </INFO>
              <ITEMS>
                <xsl:for-each select="bocb2e/trans/trn-b2e0078-rs/b2e0078-rs">
                  <ITEM>
                    <ZRSPCOD>
                      <xsl:value-of select="status/rspcod"/>
                    </ZRSPCOD>
                    <ZRSPMSG>
                      <xsl:value-of select="status/rspmsg"/>
                    </ZRSPMSG>
                    <zinsid>
                      <xsl:value-of select="insid"/>
                    </zinsid>
                    <zobssid>
                      <xsl:value-of select="obssid"/>
                    </zobssid>
                  </ITEM>
                </xsl:for-each>
              </ITEMS>
            </xsl:otherwise>
          </xsl:choose>
        </RESPONSE>
      </asx:values>
    </asx:abap>
  </xsl:template>
</xsl:transform>
View Code
复制代码

 

posted @   .我是谁  阅读(878)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示