SAP ABAP XML报文解析 以及返回XML报文处理

*&---------------------------------------------------------------------*
*& Report ZTEST
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZTEST.

DATA:pv_xml TYPE string.
TYPES: BEGIN OF typ_value,
        name  TYPE string,
         value TYPE string,
       END OF typ_value.
DATA: ls_value TYPE typ_value,
     lt_value LIKE TABLE OF ls_value.

*DATA:ls_value TYPE          znys_xml_value,
*     lt_value LIKE TABLE OF znys_xml_value.

TYPES:BEGIN OF ty_return,
     result TYPE c,"失败成功标识 0-失败 1-成功
     message TYPE c LENGTH 200,
     END OF ty_return.
DATA:lt_return TYPE TABLE OF ty_return,
     ls_return TYPE ty_return.


*  XML 解析用到的变量
TYPES: BEGIN OF xml_line,
         data(256) TYPE x,
       END OF xml_line.
DATA: l_ixml          TYPE REF TO if_ixml,
      l_document      TYPE REF TO if_ixml_document,
      l_streamfactory TYPE REF TO if_ixml_stream_factory,
      l_ostream       TYPE REF TO if_ixml_ostream,
      l_encoding      TYPE REF TO if_ixml_encoding,
      l_renderer      TYPE REF TO if_ixml_renderer.
DATA: l_element_xerp     TYPE REF TO if_ixml_element.
DATA: l_xml_table TYPE TABLE OF xml_line,
      l_xml_size  TYPE i,
      ls_xml      TYPE string,
      l_rc        TYPE i.
DATA: node_root TYPE REF TO if_ixml_element,
      node_item TYPE REF TO if_ixml_element,
      node_curr TYPE REF TO if_ixml_element.


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,
      node_parent TYPE REF TO if_ixml_node,
      attr        TYPE REF TO if_ixml_node,
      count       TYPE i.
*  定义基础变量
DATA: gv_markd TYPE c,
      gv_tabix TYPE sy-tabix,
      gv_lines TYPE i,
      gv_mode  TYPE char3.
DATA:EP_OUTPUT TYPE  ZNYMT_1200_P7MIS2ERP_HT_RETURN.
     DATA lv_guid TYPE guid_32.
SELECT SINGLE content INTO pv_xml FROM XXXXX WHERE zguid = '286ED488C68A1EEE83CE97D06A71F293' 

**1.接口日志保存
*  PERFORM save_data USING ip_input CHANGING lv_guid.

*2.XML数据解析
  PERFORM process_xml TABLES lt_value.

*3.数据处理
  PERFORM process_data TABLES lt_value CHANGING ep_output.

*4.结果更新
  PERFORM update_data USING lv_guid  ep_output.

*----------------------------------------------------------------------*
***INCLUDE LZNYFG_MM_01200F01.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  SAVE_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM save_data  USING    up_input TYPE znymt_1200_p7mis2erp_ht
                CHANGING cv_guid.

  DATA:zinfo TYPE char10.
  zinfo = '1200HT'.  "

  CALL FUNCTION 'ZTYFM_XI_LOG'
    EXPORTING
      zifno      = zinfo
      zsystem    = 'P7MIS'
      zdirection = 'IN'
      zcontent   = up_input-mt_1200_p7mis2erp_ht-output
      zresult    = ''
    IMPORTING
      ep_guid    = cv_guid.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  PROCESS_XML
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM process_xml  TABLES   ct_value STRUCTURE typ_value.
  DATA xmldata   TYPE xstring.
       DATA:cs_value TYPE znys_xml_value.
  DATA:lt_result_xml TYPE STANDARD TABLE OF smum_xmltb.
  DATA:lt_return TYPE STANDARD TABLE OF bapiret2 .
  DATA:ls_wa_xml TYPE smum_xmltb.
  CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
    EXPORTING
      text   = pv_xml
    IMPORTING
      buffer = xmldata.

  CALL FUNCTION 'SMUM_XML_PARSE'
    EXPORTING
      xml_input = xmldata
    TABLES
      xml_table = lt_result_xml
      return    = lt_return.
  "处理XML到内表,此处内表值含有节点名称,如HEAD ITEM..
  LOOP AT lt_result_xml INTO DATA(ls_result_xml) WHERE hier NE 1.
    cs_value-name = ls_result_xml-cname.
    cs_value-value = ls_result_xml-cvalue.
    APPEND cs_value TO ct_value.
  ENDLOOP.


ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  PROCESS_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM process_data  TABLES   ct_value STRUCTURE znys_xml_value
                   CHANGING cp_output TYPE znymt_1200_p7mis2erp_ht_return.
DATA:p_xml TYPE string.
"拆分head和item
 PERFORM frm_split_table TABLES ct_value lt_return.

 "返回消息处理
  PERFORM frm_tab_xml USING lt_return CHANGING p_xml.

  cp_output-mt_1200_p7mis2erp_ht_return-input = p_xml.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  UPDATE_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM update_data  USING uv_guid
                        up_output TYPE znymt_1200_p7mis2erp_ht_return.
  DATA:zinfo TYPE char10.
  zinfo = '1200HT'.  "

  CALL FUNCTION 'ZTYFM_XI_LOG_UPDATE'
    EXPORTING
      zifno   = zinfo
      zresult = up_output-mt_1200_p7mis2erp_ht_return-input
      guid    = uv_guid.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_SPLIT_TABLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PT_VALUE  text
*----------------------------------------------------------------------*
FORM FRM_SPLIT_TABLE  TABLES  pt_value STRUCTURE znys_xml_value
                              pt_return STRUCTURE ls_return.
 DATA:flg_h TYPE c VALUE 'X',"处理报文头标识
      flg_i TYPE c,"处理报文行项目标识
      lv_htlx TYPE zhtlx."合同类型
 
 LOOP AT pt_value INTO DATA(ls_value).
   CASE ls_value-name.
     WHEN 'HTSP_NO'."合同主键
      ls_znymmt00570-htsp_no = ls_value-value.
     WHEN 'HTBH'."合同编号
      ls_znymmt00570-htbh = ls_value-value.
    WHEN 'HTMC'."合同名称
      ls_znymmt00570-htmc = ls_value-value.
    WHEN 'HTLX'."合同类型
      lv_htlx = ls_value-value.
      ls_znymmt00570-htlx = ls_value-value.
    WHEN 'HTJE'."合同金额(万元)
      ls_znymmt00570-htje = ls_value-value.
     WHEN 'BUKRS'."公司
      ls_znymmt00570-bukrs = ls_value-value.
    WHEN 'WAERS'."货币
      ls_znymmt00570-waers = ls_value-value.
    WHEN 'LIFNR'."供应商编码
      ls_znymmt00570-lifnr = ls_value-value.

    WHEN 'LIFNR_MC'."供应商名称
      ls_znymmt00570-lifnr_mc = ls_value-value.
     WHEN 'KDATB'."合同开始日期
      ls_znymmt00570-kdatb = ls_value-value.
    WHEN 'KDATE'."合同结束日期
      ls_znymmt00570-kdate = ls_value-value.
    WHEN 'HTCJR'."合同创建人
      ls_znymmt00570-htcjr = ls_value-value.
    WHEN 'HTCJSJ'."合同创建时间
      ls_znymmt00570-htcjsj = ls_value-value.
     WHEN 'HTSPR'."合同审批人
      ls_znymmt00570-htspr = ls_value-value.
    WHEN 'HTSPSJ'."合同审批时间
      ls_znymmt00570-htspsj = ls_value-value.
    WHEN 'PSPNR'."项目所属WBS结构
      ls_znymmt00570-pspnr = ls_value-value.
    WHEN 'LXJE'."立项金额(万元)
      ls_znymmt00570-htspsj = ls_value-value.
    WHEN 'HTZT'."合同状态
      ls_znymmt00570-HTZT = ls_value-value.
   ENDCASE.
   IF ls_value-name = 'ITEM'.
     IF flg_h = 'X'.
       APPEND ls_znymmt00570 TO lt_znymmt00570."表头数据
     ENDIF.
     flg_h = ''.
     flg_i = 'X'.
   ENDIF.

   IF flg_i = 'X'.
    "合同行项目表(工程、服务类)
     IF lv_htlx = 'GCL' OR lv_htlx = 'FWL'.
       CASE ls_value-name.
         WHEN 'HTSP_NO'.
          ls_znymmt00580-htsp_no = ls_value-value.
         WHEN 'HTBH_H'.
          ls_znymmt00580-htbh_h = ls_value-value.
        WHEN 'ND'."年度
          ls_znymmt00580-nd = ls_value-value.
        WHEN 'FWBM'."服务编码
          ls_znymmt00580-fwbm = ls_value-value.
        WHEN 'FWMC'."服务名称
          ls_znymmt00580-fwmc = ls_value-value.
        WHEN 'MENGE'."数量
          ls_znymmt00580-menge = ls_value-value.
        WHEN 'HSDJ'."单价(万元)
          ls_znymmt00580-hsdj = ls_value-value.
        WHEN 'FJJE'."分解金额
          ls_znymmt00580-fjje = ls_value-value.
        WHEN 'NETWR'."金额(万元)
          ls_znymmt00580-netwr = ls_value-value.
        WHEN 'MWSKZ'."税率
          ls_znymmt00580-mwskz = ls_value-value.
        WHEN 'BZ'."备注
          ls_znymmt00580-bz = ls_value-value.
        WHEN 'EKGRP'."采购组
          ls_znymmt00580-ekgrp = ls_value-value.
        IF ls_znymmt00580 IS NOT INITIAL.
          APPEND ls_znymmt00580 TO lt_znymmt00580.
          CLEAR ls_znymmt00580.
        ENDIF.

       ENDCASE.
     ENDIF.

     IF lv_htlx = 'CGL'."物资类
       CASE ls_value-name.
         WHEN 'HTSP_NO'.
          ls_znymmt00590-htsp_no = ls_value-value.
         WHEN 'HTBH_H'.
          ls_znymmt00590-htbh_h = ls_value-value.
        WHEN 'WZMC'."物资名称
          ls_znymmt00590-wzmc = ls_value-value.
        WHEN 'GGXH'."规格型号
          ls_znymmt00590-ggxh = ls_value-value.
        WHEN 'HSDJ'."含税单价(元)
          ls_znymmt00590-hsdj = ls_value-value.
        WHEN 'MENGE'.
          ls_znymmt00590-menge = ls_value-value.
        WHEN 'NETWR'."含税金额(元)
          ls_znymmt00590-netwr = ls_value-value.
        WHEN 'MWSKZ'."税率 %
          ls_znymmt00590-mwskz = ls_value-value.
        WHEN 'BZ'."备注
          ls_znymmt00590-bz = ls_value-value.
        WHEN 'JHQ'."交货日期
          ls_znymmt00590-jhq = ls_value-value.
          IF ls_znymmt00590 IS NOT INITIAL.
            APPEND ls_znymmt00590 TO lt_znymmt00590.
            CLEAR ls_znymmt00590.
           ENDIF.
       ENDCASE.
     ENDIF.

   ENDIF.
 ENDLOOP.
  "报文数据检查
  PERFORM frm_check_data.


ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_TAB_XML
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LT_RETURN  text
*      <--P_P_XML  text
*----------------------------------------------------------------------*
FORM FRM_TAB_XML  USING    pt_return LIKE lt_return
                  CHANGING p_pe_xml.

 DATA: lv_name  TYPE string,
        lv_value TYPE string.
 CHECK pt_return[] IS NOT INITIAL.
*------  初始化XML
  FREE: l_document,l_ixml.
  l_ixml = cl_ixml=>create( ).
  l_document = l_ixml->create_document( ).
*  创建root 结点
  PERFORM frm_create_element USING l_document 'ROOT' l_document  '' CHANGING node_root.
*  内表数据处理
  LOOP AT pt_return INTO DATA(ps_return).
*   创建ITEM结点
    PERFORM frm_create_element USING l_document 'ITEM' node_root  '' CHANGING node_item.
*  12列
    CLEAR: gv_lines.
    DO 5 TIMES.
      CLEAR: lv_name,lv_value.
      gv_lines = gv_lines + 1.
      CASE gv_lines.
        WHEN '1'.
          lv_name = 'RESULT'.
          lv_value = ps_return-result.
        WHEN '2'.  "
          lv_name = 'MESSAGE'.
          lv_value = ps_return-message.
      ENDCASE.
      PERFORM frm_create_element USING l_document lv_name node_item  lv_value CHANGING node_curr.
    ENDDO.
  ENDLOOP.
*  数据转换
*&---------  node XML 转换
  CLEAR: l_xml_table,l_xml_size.
  l_streamfactory = l_ixml->create_stream_factory( ).

  l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ).

  l_renderer = l_ixml->create_renderer( ostream  = l_ostream
                                        document = l_document ).
  l_rc = l_renderer->render( ).

  l_xml_size = l_ostream->get_num_written_raw( ).

  CALL FUNCTION 'SCMS_BINARY_TO_STRING'
    EXPORTING
      input_length = l_xml_size
    IMPORTING
      text_buffer  = p_pe_xml
    TABLES
      binary_tab   = l_xml_table
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_CREATE_ELEMENT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_L_DOCUMENT  text
*      -->P_0576   text
*      -->P_L_DOCUMENT  text
*      -->P_0578   text
*      <--P_NODE_ROOT  text
*----------------------------------------------------------------------*
FORM FRM_CREATE_ELEMENT  USING   root_document TYPE REF TO if_ixml_document
                                  pv_name
                                  pc_parent
                                  pv_value
                         CHANGING pc_element.
  CALL METHOD root_document->create_simple_element
    EXPORTING
      name   = pv_name
      parent = pc_parent
      value  = pv_value
    RECEIVING
      rval   = pc_element.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_CHECK_DATA .
 DATA:lv_tabix TYPE sy-tabix.
  CLEAR:lt_return,ls_return.
  SORT lt_znymmt00570 BY htsp_no.
  SORT lt_znymmt00580 BY htsp_no.
  SORT lt_znymmt00590 BY htsp_no.
  LOOP AT lt_znymmt00570 INTO ls_znymmt00570.
    IF ls_znymmt00570-bukrs IS INITIAL.
       ls_return-htsp_no = ls_znymmt00570-htsp_no.
       ls_return-htbh_h = '0'."0--抬头
       ls_return-result = '0'."0--失败 1--成功
       ls_return-message = '公司代码不能为空'.
    ELSE.
      SELECT SINGLE bukrs INTO @DATA(lv_bukrs) FROM t001 WHERE bukrs = @ls_znymmt00570-bukrs.
      IF lv_bukrs IS INITIAL.
        ls_return-htsp_no = ls_znymmt00570-htsp_no.
        ls_return-htbh_h = '0'."0--抬头
        ls_return-result = '0'."0--失败 1--成功
        CONCATENATE ls_return-message '公司代码不存在!' INTO ls_return-message SEPARATED BY ','.
      ENDIF.
    ENDIF.

    IF ls_return-message IS INITIAL.
       ls_return-htsp_no = ls_znymmt00570-htsp_no.
       ls_return-htbh_h = '0'."0--抬头
       ls_return-result = '1'."0--失败 1--成功
       ls_return-message = '报文抬头检查成功!'.
    ENDIF.
    APPEND ls_return TO lt_return.
    CLEAR ls_return.
    "报文抬头字段检查后匹配行项目表进行检查
    "明细数据(工程、服务类)
     CLEAR lv_tabix.
     READ TABLE lt_znymmt00580 INTO ls_znymmt00580 WITH KEY htsp_no = ls_znymmt00570-htsp_no BINARY SEARCH.
     IF sy-subrc = 0.
       lv_tabix = sy-tabix.
       LOOP AT lt_znymmt00580 INTO ls_znymmt00580 FROM lv_tabix.
         IF ls_znymmt00580-htsp_no <> ls_znymmt00570-htsp_no.
           EXIT.
         ENDIF.
         IF ls_znymmt00580-nd IS INITIAL.
           ls_return-result = '0'."0--失败 1--成功
           ls_return-message = '年度字段不能为空'.
           APPEND ls_return TO lt_return.
           CLEAR ls_return.
         ENDIF.
         IF ls_return-result IS INITIAL.
           ls_return-result = '1'."0--失败 1--成功
           ls_return-message = '数据检查成功'.
           APPEND ls_return TO lt_return.
           CLEAR ls_return.
         ENDIF.
       ENDLOOP.
     ENDIF.
     "明细数据物资类
     CLEAR lv_tabix.
     READ TABLE lt_znymmt00590 INTO ls_znymmt00590 WITH KEY htsp_no = ls_znymmt00570-htsp_no BINARY SEARCH.
     IF sy-subrc = 0.
       lv_tabix = sy-tabix.
       LOOP AT lt_znymmt00590 INTO ls_znymmt00590 FROM lv_tabix.
         IF ls_znymmt00590-htsp_no <> ls_znymmt00570-htsp_no.
           EXIT.
         ENDIF.
         IF ls_znymmt00590-ggxh IS INITIAL.
           ls_return-result = '0'."0--失败 1--成功
           ls_return-message = '规格型号字段不能为空'.
           APPEND ls_return TO lt_return.
           CLEAR ls_return.
         ENDIF.
         IF ls_return-result IS INITIAL.
           ls_return-result = '1'."0--失败 1--成功
           ls_return-message = '数据检查成功'.
           APPEND ls_return TO lt_return.
           CLEAR ls_return.
         ENDIF.
       ENDLOOP.
     ENDIF.
  ENDLOOP.
ENDFORM.

 

posted @ 2023-07-07 11:02  年轻的小菜鸟  阅读(738)  评论(0编辑  收藏  举报