ABAP:ABAP解析xml文件的方法

文章介绍了在SAPECC系统中解析XML的两种方法:一是通过STRANS创建转化例程进行转换,二是直接使用SAP方法按节点解析。示例展示了XML文件内容及转化结构,并提供了STRANS转化例程的代码和调用方式,以及基于节点解析的SAP内建方法的处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前我在ECC的系统找到两种实现XML解析的办法,第一种是通过strans创建转化例程,然后在程序中调用转化例程来转化xml,第二种是调用方法按照node解析xml。

要转化的xml文件demo如下

<?xml version="1.0" encoding="Windows-1252"?>
<PPSExport Version="1.1">
    <ProductionOperationFeedback>
        <Operation OrderNo="600001099">
            <OperationNo>0010</OperationNo>
            <PartNo>210402000001</PartNo>
            <WorkPlace>TruLaserCenter7030-1</WorkPlace>
            <CostCenter />
            <TimeStamp>21.06.2023 09:10:21</TimeStamp>
            <ReturnType>30</ReturnType>
            <ProcessedParts>3</ProcessedParts>
            <ScrapParts>0</ScrapParts>
            <MissingParts>0</MissingParts>
            <TargetProcessingTimePerPiece>0.35</TargetProcessingTimePerPiece>
            <ProcessingTime>3.4500</ProcessingTime>
            <SetupTime>0.0000</SetupTime>
            <MeasuringTime>0.0000</MeasuringTime>
            <OperationStart>21.06.2023 09:09:45</OperationStart>
            <OperationEnd>21.06.2023 09:10:21</OperationEnd>
            <PartWeight>3.93622</PartWeight>
            <PartArea>0.41892516</PartArea>
            <PartLength>1210.00000</PartLength>
            <PartWidth>490.60000</PartWidth>
            <Assembly>100260031100</Assembly>
            <DataExt />
            <OrderNoExt />
            <CollectiveOrder>10000176</CollectiveOrder>
            <ErpID />
            <QuantityReports>
                <QuantityReport>
                    <ReportingTime>21.06.2023 09:10:21</ReportingTime>
                    <ProcessedParts>3</ProcessedParts>
                    <ScrapParts>0</ScrapParts>
                    <MissingParts>0</MissingParts>
                    <BatchNo>123456</BatchNo>
                    <WorkPlace>TruLaserCenter7030-1</WorkPlace>
                    <ReportedBy>0101????</ReportedBy>
                    <Terminal>LAP361347</Terminal>
                </QuantityReport>
            </QuantityReports>
            <Consumption>
                <ResourceConsumption ResourceName="300102010012" ResourceType="20">
                    <ResourceDescription>300102010012</ResourceDescription>
                    <ResourceNote>DC01-012 3000x1250</ResourceNote>
                    <ResourceCategory />
                    <Consumption>3.75000</Consumption>
                    <UnitOfConsumption>m2</UnitOfConsumption>
                    <Rawmaterial>300102010012</Rawmaterial>
                    <Dimensions>
                        <Length>3000.00000</Length>
                        <Width>1250.00000</Width>
                        <Thickness>1.20000</Thickness>
                        <Unit>mm</Unit>
                    </Dimensions>
                </ResourceConsumption>
            </Consumption>
        </Operation>
    </ProductionOperationFeedback>
</PPSExport>

转化的结构定义如下

types: begin of ty_report,
  reportingtime type string,
  processedparts type string,
  scrapparts type string,
  missingparts type string,
  batchno type string,
  workplace type string,
  reportedby type string,
  terminal type string,
  end of ty_report.

types: begin of ty_reports,
  quantityreport type ty_report,
  end of ty_reports.

types: begin of ty_dimensions,
  length type string,
  width type string,
  thickness type string,
  unit type string,
  end of   ty_dimensions.

types: begin of ty_resourceconsumption,
*    resourcename TYPE string,
*    resourcetype TYPE string,
  resourcedescription type string,
  resourcenote type string,
  resourcecategory type string,
  consumption type string,
  unitofconsumption type string,
  rawmaterial type string,
  dimensions type ty_dimensions,
  end of ty_resourceconsumption.


data: lt_resourceconsumption type table of ty_resourceconsumption,
      ls_resourceconsumption type ty_resourceconsumption.

types: begin of ty_resourceconsumptions,
resourceconsumption like lt_resourceconsumption,
  end of ty_resourceconsumptions.

types: begin of ty_order,
  orderno type string,
  operationno type string,
  partno type string,
  workplace type string,
  costcenter type string,
  timestamp type string,
  returntype type string,
  processedparts type string,
  scrapparts type string,
  missingparts type string,
  targetprocessingtimeperpiece type string,
  processingtime type string,
  setuptime type string,
  measuringtime type string,
  operationstart type string,
  operationend type string,
  partweight type string,
  partarea type string,
  partlength type string,
  partwidth type string,
  assembly type string,
  dataext type string,
  ordernoext type string,
  collectiveorder type string,
  erpid type string,

  quantityreports type ty_reports,


  consumption type ty_resourceconsumptions,
end of ty_order.

方法一:STRANS

在事务码STRANS中创建转化例程:

 strans代码如下:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

  <tt:root name="ROOT"/>

  <tt:template>
    <PPSExport Version="1.1">
      <ProductionOperationFeedback>
        <Operation>
          <OrderNo>
            <tt:value ref="ROOT.ORDERNO"/>
          </OrderNo>
          <OperationNo>
            <tt:value ref="ROOT.OPERATIONNO"/>
          </OperationNo>
          <PartNo>
            <tt:value ref="ROOT.PARTNO"/>
          </PartNo>
          <WorkPlace>
            <tt:value ref="ROOT.WORKPLACE"/>
          </WorkPlace>
          <CostCenter>
            <tt:value ref="ROOT.COSTCENTER"/>
          </CostCenter>
          <TimeStamp>
            <tt:value ref="ROOT.TIMESTAMP"/>
          </TimeStamp>
          <ReturnType>
            <tt:value ref="ROOT.RETURNTYPE"/>
          </ReturnType>
          <ProcessedParts>
            <tt:value ref="ROOT.PROCESSEDPARTS"/>
          </ProcessedParts>
          <ScrapParts>
            <tt:value ref="ROOT.SCRAPPARTS"/>
          </ScrapParts>
          <MissingParts>
            <tt:value ref="ROOT.MISSINGPARTS"/>
          </MissingParts>
          <TargetProcessingTimePerPiece>
            <tt:value ref="ROOT.TARGETPROCESSINGTIMEPERPIECE"/>
          </TargetProcessingTimePerPiece>
          <ProcessingTime>
            <tt:value ref="ROOT.PROCESSINGTIME"/>
          </ProcessingTime>
          <SetupTime>
            <tt:value ref="ROOT.SETUPTIME"/>
          </SetupTime>
          <MeasuringTime>
            <tt:value ref="ROOT.MEASURINGTIME"/>
          </MeasuringTime>
          <OperationStart>
            <tt:value ref="ROOT.OPERATIONSTART"/>
          </OperationStart>
          <OperationEnd>
            <tt:value ref="ROOT.OPERATIONEND"/>
          </OperationEnd>
          <PartWeight>
            <tt:value ref="ROOT.PARTWEIGHT"/>
          </PartWeight>
          <PartArea>
            <tt:value ref="ROOT.PARTAREA"/>
          </PartArea>
          <PartLength>
            <tt:value ref="ROOT.PARTLENGTH"/>
          </PartLength>
          <PartWidth>
            <tt:value ref="ROOT.PARTWIDTH"/>
          </PartWidth>
          <Assembly>
            <tt:value ref="ROOT.ASSEMBLY"/>
          </Assembly>
          <DataExt>
            <tt:value ref="ROOT.DATAEXT"/>
          </DataExt>
          <OrderNoExt>
            <tt:value ref="ROOT.ORDERNOEXT"/>
          </OrderNoExt>
          <CollectiveOrder>
            <tt:value ref="ROOT.COLLECTIVEORDER"/>
          </CollectiveOrder>
          <ErpID>
            <tt:value ref="ROOT.ERPID"/>
          </ErpID>

          <QuantityReports tt:ref="ROOT.QUANTITYREPORTS">
            <QuantityReport>
              <ReportingTime>
                <tt:value ref="QUANTITYREPORT.REPORTINGTIME"/>
              </ReportingTime>
              <ProcessedParts>
                <tt:value ref="QUANTITYREPORT.PROCESSEDPARTS"/>
              </ProcessedParts>
              <ScrapParts>
                <tt:value ref="QUANTITYREPORT.SCRAPPARTS"/>
              </ScrapParts>
              <MissingParts>
                <tt:value ref="QUANTITYREPORT.MISSINGPARTS"/>
              </MissingParts>
              <BatchNo>
                <tt:value ref="QUANTITYREPORT.BATCHNO"/>
              </BatchNo>
              <WorkPlace>
                <tt:value ref="QUANTITYREPORT.WORKPLACE"/>
              </WorkPlace>
              <ReportedBy>
                <tt:value ref="QUANTITYREPORT.REPORTEDBY"/>
              </ReportedBy>
              <Terminal>
                <tt:value ref="QUANTITYREPORT.TERMINAL"/>
              </Terminal>
            </QuantityReport>
          </QuantityReports>

          <Consumption tt:ref="ROOT.CONSUMPTION">
            <tt:loop name="item" ref="RESOURCECONSUMPTION">
              <ResourceConsumption>
                <ResourceDescription>
                  <tt:value ref="$item.RESOURCEDESCRIPTION"/>
                </ResourceDescription>
                <ResourceNote>
                  <tt:value ref="$item.RESOURCENOTE"/>
                </ResourceNote>
                <ResourceCategory>
                  <tt:value ref="$item.RESOURCECATEGORY"/>
                </ResourceCategory>
                <Consumption>
                  <tt:value ref="$item.CONSUMPTION"/>
                </Consumption>
                <UnitOfConsumption>
                  <tt:value ref="$item.UNITOFCONSUMPTION"/>
                </UnitOfConsumption>
                <Rawmaterial>
                  <tt:value ref="$item.RAWMATERIAL"/>
                </Rawmaterial>

                <Dimensions>
                  <Length>
                    <tt:value ref="$item.DIMENSIONS.LENGTH"/>
                  </Length>
                  <Width>
                    <tt:value ref="$item.DIMENSIONS.WIDTH"/>
                  </Width>
                  <Thickness>
                    <tt:value ref="$item.DIMENSIONS.THICKNESS"/>
                  </Thickness>
                  <Unit>
                    <tt:value ref="$item.DIMENSIONS.UNIT"/>
                  </Unit>

                </Dimensions>
              </ResourceConsumption>
            </tt:loop>
          </Consumption>



        </Operation>
      </ProductionOperationFeedback>
    </PPSExport>
  </tt:template>

</tt:transform>

转化的输入结构(部分截图)如下: 

 STRAN的调用方式如下:

  data: lo_cx_st_match_element type ref to cx_st_match_element,
        lv_message type string.   
 data: ls_input type ty_order.
 TRY.
        CALL TRANSFORMATION zxxx
             SOURCE XML lv_xml
             RESULT root =  ls_input.

      CATCH cx_st_match_element INTO lo_cx_st_match_element.
        lv_message = lo_cx_st_match_element->get_text( ).

        ev_type = 'E'.
        ev_mess = '传入XML文件解析有误'.

    ENDTRY.

 方法二:调用SAP方法按照node来解析xml

 if lv_xml is not initial.

    try.
*        CALL TRANSFORMATION zmes004_input
*             SOURCE XML lv_xml
*             RESULT root =  ls_input.
        l_ixml = cl_ixml=>create( ).
        l_streamfactory = l_ixml->create_stream_factory( ).

        l_istream = l_streamfactory->create_istream_string(
                                       string = lv_xml ).
        l_document = l_ixml->create_document( ).
        l_parser = l_ixml->create_parser(
                             stream_factory = l_streamfactory
                             istream        = l_istream
                             document       = l_document ).

        if l_parser->parse( ) ne 0.
          if l_parser->num_errors( ) ne 0.
            l_parse_error = l_parser->get_error( index = l_index ).
            ev_type = 'E'.
            ev_mess = 'xml解析有误'.
          endif.
        endif.

        if l_parser->is_dom_generating( ) eq 'X'.
          perform frm_process_dom_bg using l_document
                               changing ls_input.
        endif.
      catch cx_st_match_element into lo_cx_st_match_element.
        lv_message = lo_cx_st_match_element->get_text( ).

        ev_type = 'E'.
        ev_mess = '传入XML文件解析有误'.

    endtry.
form frm_process_dom_bg using l_document type ref to if_ixml_document
                   changing ps_stru type ty_order.
  data: lo_node      type ref to if_ixml_node,
        lo_iterator  type ref to if_ixml_node_iterator.
  data: lo_nodemap type ref to if_ixml_named_node_map.
  data: lo_nodelist2   type ref to if_ixml_node_list,
        lo_nodelist3   type ref to if_ixml_node_list,
        lo_node2      type ref to if_ixml_node,
        lo_node3      type ref to if_ixml_node.
  data: lv_name_node type string.
  data: lv_name type char30,
        lv_value type string.
  data: lv_count type i,
        lv_index type sy-index,
        lv_prefix type string.
  data lo_attr type ref to if_ixml_node.
  field-symbols: <fs_field>,
                 <fs_field1>,
                 <fs_field2>.
  data: ls_quantityreport type ty_report.
  data: ls_resourceconsumption type ty_resourceconsumption,
        lt_resourceconsumption type table of ty_resourceconsumption.
  data: ls_dimensions type ty_dimensions.


  lo_node ?= l_document.

  check not lo_node is initial.

  lo_iterator  = lo_node->create_iterator( ).
  lo_node = lo_iterator->get_next( ).

  data lv_type type i.
  while not lo_node is initial.
    lv_type = lo_node->get_type( ).
    case lv_type.
      when if_ixml_node=>co_node_element.
        lv_name_node  = lo_node->get_name( ).
        lv_name = lv_name_node.
        translate lv_name to upper case.

        if lv_name = 'OPERATION'.

          lo_nodemap = lo_node->get_attributes( ).
          if not lo_nodemap is initial.
            lv_count = lo_nodemap->get_length( ).
            do lv_count times.
              lv_index  = sy-index - 1.
              lo_attr   = lo_nodemap->get_item( lv_index ).
              lv_name_node   = lo_attr->get_name( ).
              lv_name = lv_name_node.
              translate lv_name to upper case.
              assign component lv_name of structure ps_stru to <fs_field>.
              lv_prefix = lo_attr->get_namespace_prefix( ).
              lv_value  = lo_attr->get_value( ).
              if <fs_field> is assigned.
                if lv_value is not initial.
                  <fs_field> = lv_value.
                endif.
              endif.
              if lv_name = 'ORDERNO'.
                exit.
              endif.
            enddo.
          endif.
        elseif lv_name = 'REPORTINGTIME' or lv_name = 'PROCESSEDPARTS' or
                lv_name = 'SCRAPPARTS' or lv_name = 'MISSINGPARTS' or
                lv_name = 'BATCHNO' or lv_name = 'WORKPLACE' or
                lv_name = 'REPORTEDBY' or lv_name = 'TERMINAL'.

          assign component lv_name of structure ls_quantityreport to <fs_field>.
        elseif lv_name = 'RESOURCEDESCRIPTION' or lv_name = 'RESOURCENOTE' or
                lv_name = 'RESOURCECATEGORY' or lv_name = 'CONSUMPTION' or
                lv_name = 'UNITOFCONSUMPTION' or lv_name = 'RAWMATERIAL' .

          assign component lv_name of structure ls_resourceconsumption to <fs_field>.
        elseif lv_name = 'LENGTH' or lv_name = 'WIDTH' or
               lv_name = 'THICKNESS' or lv_name = 'UNIT'.
          assign component lv_name of structure ls_dimensions to <fs_field>.
        else.
          assign component lv_name of structure ps_stru to <fs_field>.
        endif.
      when if_ixml_node=>co_node_text or
           if_ixml_node=>co_node_cdata_section.

        lv_value = lo_node->get_value( ).
        if <fs_field> is assigned.
          <fs_field> = lv_value.
        endif.
        if lv_name = 'UNIT'..
          ls_resourceconsumption-dimensions = ls_dimensions.
          append ls_resourceconsumption to lt_resourceconsumption.
          clear ls_resourceconsumption.
          clear ls_dimensions.
        endif.
    endcase.
    clear:lo_node,lo_nodemap,lo_attr,lv_name_node.
    clear:lv_prefix,lv_value,lv_count,lv_index.
    lo_node = lo_iterator->get_next( ).

  endwhile.

  clear:lo_node,lo_iterator.
  ps_stru-quantityreports-quantityreport = ls_quantityreport.
  ps_stru-consumption-resourceconsumption = lt_resourceconsumption.
  unassign <fs_field>.
endform.                    "process_dom

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值