ABAP:ABAP解析xml文件的方法

目前我在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

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将XML文件解析为内表,并在ALV中显示输出,你可以使用以下步骤: 1. 创建ABAP结构:首先,你需要创建一个与XML文件中的数据结构相对应的ABAP结构。确保结构字段与XML元素或属性名称匹配。 2. 定义内表:创建一个内表,使用上一步创建的ABAP结构作为表行类型。 3. 使用XML解析解析XML文件:使用`cl_xml_document`类创建一个XML文档对象,并使用`load`方法加载XML文件。 ```abap DATA: lo_xml_document TYPE REF TO if_ixml_document, lv_file_path TYPE string. lv_file_path = '<XML_FILE_PATH>'. "替换为你的XML文件路径 CREATE OBJECT lo_xml_document. lo_xml_document->load( lv_file_path ). ``` 4. 获取根节点:通过调用`get_root_node`方法获取XML文档的根节点。 ```abap DATA: lo_root_node TYPE REF TO if_ixml_node. lo_root_node = lo_xml_document->get_root_node( ). ``` 5. 遍历XML节点并解析数据:使用循环遍历子节点,并使用`get_attribute_value`方法获取节点属性值,使用`get_text`方法获取节点文本内容。将解析后的数据填充到内表中。 ```abap DATA: lt_data TYPE TABLE OF your_structure, ls_data TYPE your_structure, lo_child_node TYPE REF TO if_ixml_node. lo_child_node = lo_root_node->get_child_nodes( 'NodeName' ). "替换为你的节点名称 WHILE lo_child_node IS BOUND. ls_data-field1 = lo_child_node->get_attribute_value( 'AttributeName' ). "替换为你的属性名称 ls_data-field2 = lo_child_node->get_text( ). APPEND ls_data TO lt_data. lo_child_node = lo_child_node->get_next_sibling( ). ENDWHILE. ``` 6. 显示数据在ALV中:使用ALV控制台类(`cl_salv_table`)创建一个ALV对象,并使用`set_table`方法将内表数据传递给ALV对象。 ```abap DATA: lo_alv_table TYPE REF TO cl_salv_table. CREATE OBJECT lo_alv_table. lo_alv_table->set_table( lt_data ). ``` 7. 显示ALV表格:使用`display`方法显示ALV表格。 ```abap lo_alv_table->display( ). ``` 这样,你就可以将XML文件解析为内表,并在ALV中显示输出。请根据实际情况修改上述代码,并确保ABAP结构与XML文件的结构匹配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值