SAP ABAP端实现解析具有深层结构的文件内容(类似SAP PO中的FCC功能)

news2024/11/26 9:38:30

前言

日本项目经常需要通过PI或者CPI去解析一些文件内容,如果只是扁平结构的,不涉及头行结构的话,在PI中可以FCC(File Content Conversion)进行解析转换,在CPI中可以使用groovy脚本进行解析转换,但是如果涉及头行层级关系的,PI中不支持通过FCC进行转换,但是可以通过一些自定义的转换Bean来进行转换,不过需要自己去编写java代码去实现,并导出为EAR文件部署到PI服务器上才可以,当时没有现成的java解析代码,考虑到实现这个功能的时间成本问题,最终选择在SAP端实现这个解析功能。

需求

源文件内容如下:

A012A010123456789
A0200010ABCDEFGHI12345678
A012A010123456789
A0200010ABCDEFGHI12345678
A0200020ABCDEFGHI12345678

转换规则:

第2位~第3位为01的为抬头数据,第2位~第3位为02的为明细数据。

预期目标XML格式:

<root>
	<head>
		<type>A</type>
		<subtype>01</subtype>
		<company>2A01</company>
		<description>0123456789</description>
		<items>
			<item>
				<type>A</type>
				<subtype>02</subtype>
				<itemno>00010</itemno>
				<text1>ABCDEFGHI</text1>
				<text2>12345678</text2>
			</item>
		</items>
	</head>
	<head>
		<type>A</type>
		<subtype>01</subtype>
		<company>2A01</company>
		<description>0123456789</description>
		<items>
			<item>
				<type>A</type>
				<subtype>02</subtype>
				<itemno>00010</itemno>
				<text1>ABCDEFGHI</text1>
				<text2>12345678</text2>
			</item>
			<item>
				<type>A</type>
				<subtype>02</subtype>
				<itemno>00020</itemno>
				<text1>ABCDEFGHI</text1>
				<text2>12345678</text2>
			</item>
		</items>
	</head>
</root>

但实际上PI并不支持这种层级转换,通过FCC配置只能达到平级的效果,配置如下:

转换结果:

<?xml version="1.0" encoding="utf-8"?>
<ns:MT_FTP2SAP_HD xmlns:ns="urn:psam:ftp2sap_test_head_item">
	<head>
		<type>A</type>
		<subtype>01</subtype>
		<company>2A01</company>
		<description>0123456789</description>
	</head>
	<item>
		<type>A</type>
		<subtype>02</subtype>
		<itemno>00010</itemno>
		<text1>ABCDEFGHI</text1>
		<text2>12345678</text2>
	</item>
	<head>
		<type>A</type>
		<subtype>01</subtype>
		<company>2A01</company>
		<description>0123456789</description>
	</head>
	<item>
		<type>A</type>
		<subtype>02</subtype>
		<itemno>00010</itemno>
		<text1>ABCDEFGHI</text1>
		<text2>12345678</text2>
	</item>
	<item>
		<type>A</type>
		<subtype>02</subtype>
		<itemno>00020</itemno>
		<text1>ABCDEFGHI</text1>
		<text2>12345678</text2>
	</item>
</ns:MT_FTP2SAP_HD>

这样平级的转换效果,就失去了层级的关联关系,由于源文件中的数据是没有主键信息可以互相关联的,只能通过每一行的位置来判定是不是上一行的明细行,所以这样的转换结果是不行的,所以后来采用将每一行字符串完整的接收到SAP,在SAP端进行解析,考虑到类似的接口比较多,不想每一本单独去写解析规则,所以我在SAP端封装了一个共通的解析工具类,可以通过传入一些可配置的解析参数,来动态进行解析。

通过FCC转换文件到XML可以参考我的另一篇帖子:

SAP PI/PO File2Soap 发送方使用Content Conversion将文本格式转换为XML格式icon-default.png?t=N7T8https://blog.csdn.net/DeveloperMrMeng/article/details/130868786?spm=1001.2014.3001.5501


实现效果

1.测试数据内容:

2.解析规则参数传值:

重要参数说明:

STRUCTURE:包含哪几种类型的解析规则。

KEYFNAME:每种类型的判定依据,该字段要在每种类型的结构中都有。

<类型n>.FIELDNAMES:该类型包含哪些字段。

<类型n>.FIELDLEN:每个字段的长度,框架会按照指定长度去解析。

<类型n>.FIELDLENTYPE:解析长度的类型,BYTE为按字节长度解析,STRING为按照字符长度,不指定默认为STRING。

<类型n>.PARENT:指定父节点,如果该节点为顶层节点,则指定为ROOT即可,或不指定该参数。

3.调用解析工具类:

4.解析结果:

同理,只需要根据参数指定不同的层级关系,即可达到不同的解析效果:

①:将item 和 details均指定为 head 的子节点

②:只需要解析 head 数据。

借助该解析工具类,即可实现通过配置的方式来动态解析文件内容,并且同样适用于本地文件直接通过GUI_UPLOAD的方式上传后去进行解析。

工具类源码

实现过程中要考虑的问题点还是蛮多的,要考虑通用性的问题,所以要考虑的尽可能全面一些,工具类主要使用了一些递归方法,以及创建结构、表的一些SAP标准工具类,测试demo程序源码也会在下面附上,感兴趣的可以自己创建一下,debug一下。

CLASS zprbccl_convert_file2table DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    TYPES:
      BEGIN OF ty_line,
        name TYPE zprbcestring,
        line TYPE REF TO data,
      END OF ty_line .
    TYPES:
      tt_line   TYPE STANDARD TABLE OF ty_line .
    TYPES:
      tt_string TYPE STANDARD TABLE OF string .
    TYPES:
      BEGIN OF ty_source_data,
        data TYPE string,
      END OF ty_source_data .
    TYPES:
      tt_source_data TYPE STANDARD TABLE OF ty_source_data .
    TYPES:
      BEGIN OF ty_convert_rule,
        param TYPE string,
        value TYPE string,
      END OF ty_convert_rule .
    TYPES:
      tt_convert_rule TYPE STANDARD TABLE OF ty_convert_rule .

    CLASS-METHODS convert_file2table
      IMPORTING
        !it_source_data  TYPE tt_source_data
        !it_convert_rule TYPE tt_convert_rule
      EXPORTING
        !es_result       TYPE REF TO data
        !et_error        TYPE bapiret2_t
      EXCEPTIONS
        convert_failed .
  PROTECTED SECTION.
  PRIVATE SECTION.

    CLASS-DATA mt_struc_name TYPE zprbctstring .
    CLASS-DATA mt_line TYPE tt_line .
    CLASS-DATA mt_line_type TYPE zprbct_convert_line_type .
    CLASS-DATA mt_final_components TYPE abap_component_tab .

    CLASS-METHODS add_component
      IMPORTING
        !iv_fname        TYPE string
        !iv_data_element TYPE any
      CHANGING
        !ct_components   TYPE abap_component_tab .
    CLASS-METHODS build_component
      IMPORTING
        !it_source_data  TYPE tt_source_data
        !it_convert_rule TYPE tt_convert_rule
        !iv_strucname    TYPE string
      CHANGING
        !ct_components   TYPE abap_component_tab
        !ct_error        TYPE bapiret2_t .
    CLASS-METHODS fill_line
      IMPORTING
        !is_source_data  TYPE ty_source_data
        !it_convert_rule TYPE tt_convert_rule
      CHANGING
        !cs_struc        TYPE any
        !ct_error        TYPE bapiret2_t .
    CLASS-METHODS add_data_to_mt_line
      IMPORTING
        !iv_struc_name      TYPE string
        !it_sep_field_value TYPE tt_string .
    CLASS-METHODS update_child_to_mt_line
      IMPORTING
        !iv_struc_name      TYPE string
        !it_sep_field_value TYPE tt_string
        !it_convert_rule    TYPE tt_convert_rule .
    CLASS-METHODS update_target_child_table
      IMPORTING
        !iv_struc_name      TYPE string
        !it_sep_field_value TYPE tt_string
      CHANGING
        !ct_parent_list     TYPE tt_string
        !ct_line            TYPE any .
ENDCLASS.



CLASS ZPRBCCL_CONVERT_FILE2TABLE IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>ADD_COMPONENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_FNAME                       TYPE        STRING
* | [--->] IV_DATA_ELEMENT                TYPE        ANY
* | [<-->] CT_COMPONENTS                  TYPE        ABAP_COMPONENT_TAB
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD add_component.
    DATA:
      lo_type       TYPE REF TO cl_abap_typedescr,
      ls_compoments TYPE abap_componentdescr.

    ls_compoments-name = iv_fname.

    CALL METHOD cl_abap_datadescr=>describe_by_name
      EXPORTING
        p_name         = iv_data_element
      RECEIVING
        p_descr_ref    = lo_type
      EXCEPTIONS
        type_not_found = 1
        OTHERS         = 2.

    ls_compoments-type ?= lo_type.
    APPEND ls_compoments TO ct_components.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>ADD_DATA_TO_MT_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_STRUC_NAME                  TYPE        STRING
* | [--->] IT_SEP_FIELD_VALUE             TYPE        TT_STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD add_data_to_mt_line.
    DATA:
      ls_line  TYPE ty_line,
      lo_struc TYPE REF TO data.

    READ TABLE mt_line_type INTO DATA(ls_line_type)
      WITH KEY name = iv_struc_name.

    CREATE DATA lo_struc TYPE HANDLE ls_line_type-type.
    ASSIGN lo_struc->* TO FIELD-SYMBOL(<fs_new_struc>).

    LOOP AT it_sep_field_value INTO DATA(ls_field_value).
      ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_new_struc> TO FIELD-SYMBOL(<fs_field_value>).
      IF <fs_field_value> IS ASSIGNED.
        <fs_field_value> = ls_field_value.
      ENDIF.
      UNASSIGN <fs_field_value>.
    ENDLOOP.

    ls_line-name = iv_struc_name.
    ls_line-line = lo_struc.
    APPEND ls_line TO mt_line.
    CLEAR ls_line.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>BUILD_COMPONENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_SOURCE_DATA                 TYPE        TT_SOURCE_DATA
* | [--->] IT_CONVERT_RULE                TYPE        TT_CONVERT_RULE
* | [--->] IV_STRUCNAME                   TYPE        STRING
* | [<-->] CT_COMPONENTS                  TYPE        ABAP_COMPONENT_TAB
* | [<-->] CT_ERROR                       TYPE        BAPIRET2_T
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD build_component.
    DATA:
      ls_error TYPE bapiret2.

    DATA:
      lt_struc_name TYPE STANDARD TABLE OF string,
      lt_fnames     TYPE STANDARD TABLE OF string,
      lt_flen       TYPE STANDARD TABLE OF string,
      lv_param      TYPE string.

    DATA:
      lt_components TYPE abap_component_tab,
      ls_compoments TYPE abap_componentdescr,
      lo_strucdescr TYPE REF TO cl_abap_structdescr,
      lo_tabledescr TYPE REF TO cl_abap_tabledescr,
      lo_struc      TYPE REF TO data,
      lo_table      TYPE REF TO data.

    DATA:
      ls_line_type TYPE zprbcs_convert_line_type.

    DATA:
      lo_excep_table_creation  TYPE REF TO cx_sy_table_creation,
      lo_excep_struct_creation TYPE REF TO cx_sy_struct_creation.

**********************************************************************
*   Check Paramters
**********************************************************************
*   <Structure>.FIELDNAMES
    lv_param = iv_strucname && '.FIELDNAMES'.

    READ TABLE it_convert_rule INTO DATA(ls_conver_fnames)
      WITH KEY param = lv_param.
    IF sy-subrc <> 0.
      ls_error-type    = 'E'.
      ls_error-message = 'Parameter "<Structure>.FIELDNAMES" is requeried.'(002).
      APPEND ls_error TO ct_error.
      RETURN.
    ELSE.
      SPLIT ls_conver_fnames-value AT ',' INTO TABLE lt_fnames.

*     <Structure>.FIELDSEPARATOR
      lv_param = iv_strucname && '.FIELDSEPARATOR'.

      READ TABLE it_convert_rule INTO DATA(ls_conver_fsep)
        WITH KEY param = lv_param.

*     <Structure>.FIELDLEN
      lv_param = iv_strucname && '.FIELDLEN'.

      READ TABLE it_convert_rule INTO DATA(ls_conver_flen)
        WITH KEY param = lv_param.

      IF ls_conver_fsep IS INITIAL AND ls_conver_flen IS INITIAL.
        ls_error-type    = 'E'.
        ls_error-message = 'Parameter "<Structure>.FIELDLEN" and "<Structure>.FIELDSEPARATOR" require at least one.'(003).
        APPEND ls_error TO ct_error.
        RETURN.
      ENDIF.

      IF ls_conver_flen IS NOT INITIAL.
        SPLIT ls_conver_flen-value AT ',' INTO TABLE lt_flen.

        IF lines( lt_fnames ) <> lines( lt_flen ).
          ls_error-type    = 'E'.
          ls_error-message = '"<Structure>.FIELDNAMES" and "<Structure>.FIELDLEN" do not match.'(004).
          APPEND ls_error TO ct_error.
          RETURN.
        ENDIF.
      ENDIF.
    ENDIF.

    CHECK ct_error IS INITIAL.

**********************************************************************
*   Build Structure
**********************************************************************
    LOOP AT lt_fnames INTO DATA(ls_fnames).
*     Add Field
      add_component(
        EXPORTING
          iv_fname        = ls_fnames
          iv_data_element = 'ZPRBCESTRING'
        CHANGING
          ct_components   = ct_components
      ).
    ENDLOOP.

    LOOP AT it_convert_rule INTO DATA(ls_convert_parent)
      WHERE value = iv_strucname
        AND param CS '.PARENT'.

      lv_param = shift_right( val = ls_convert_parent-param
                              sub = '.PARENT' ).
*     Build Child Structure
      build_component(
        EXPORTING
          it_source_data  = it_source_data
          it_convert_rule = it_convert_rule
          iv_strucname    = lv_param
        CHANGING
          ct_components   = lt_components
          ct_error        = ct_error
       ).

      IF ct_error IS INITIAL.

        DELETE mt_struc_name WHERE table_line = lv_param.

        TRY.
*           Get line type
            CALL METHOD cl_abap_structdescr=>create
              EXPORTING
                p_components = lt_components
              RECEIVING
                p_result     = lo_strucdescr.

            ls_line_type-name = lv_param.
            ls_line_type-type = lo_strucdescr.
            APPEND ls_line_type TO mt_line_type.
            CLEAR ls_line_type.

            TRY.
*               Get table type
                CALL METHOD cl_abap_tabledescr=>create
                  EXPORTING
                    p_line_type = lo_strucdescr
                  RECEIVING
                    p_result    = lo_tabledescr.

*               Add Child field as Table Type
                ls_compoments-name =  lv_param.
                ls_compoments-type ?= lo_tabledescr.
                APPEND ls_compoments TO ct_components.
                CLEAR:
                  ls_compoments,
                  lt_components.

              CATCH cx_sy_table_creation INTO lo_excep_table_creation.
                ls_error-type    = 'E'.
                ls_error-message = lo_excep_table_creation->get_text( ).
                APPEND ls_error TO ct_error.
                RETURN.
            ENDTRY.
          CATCH cx_sy_struct_creation INTO lo_excep_struct_creation.
            ls_error-type    = 'E'.
            ls_error-message = lo_excep_struct_creation->get_text( ).
            APPEND ls_error TO ct_error.
            RETURN.
        ENDTRY.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZPRBCCL_CONVERT_FILE2TABLE=>CONVERT_FILE2TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_SOURCE_DATA                 TYPE        TT_SOURCE_DATA
* | [--->] IT_CONVERT_RULE                TYPE        TT_CONVERT_RULE
* | [<---] ES_RESULT                      TYPE REF TO DATA
* | [<---] ET_ERROR                       TYPE        BAPIRET2_T
* | [EXC!] CONVERT_FAILED
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD convert_file2table.
**********************************************************************
* This method is used to parse files into the internal table.
*   # 1.you can convert simple file to internal table.
*   # 2.you can convert deep structure file to deep internal table.
*   # 3.you can split line data by symbol or fix length(BYTE/STRING).
*   # 4.if the data has diffrent type,KEYNAME and KEYVALUE attribute must defined.
*
* Author:HAND15
* Date:  20230823
*
* Example:
*  *------------------------------------------------------------------
*  | ①Simple file source data:
*  *------------------------------------------------------------------
*     A012A011234567890
*     A012A029876543210
*  *------------------------------------------------------------------
*  |  Convert rule
*  *------------------------------------------------------------------
*    [PARAM]           |     [VALUE]
*     STRUCTURE               HEAD
*     HEAD.FIELDNAMES         TYPE,KEY,BUKRS,VBELN
*     HEAD.FIELDLEN           1,2,4,10
*     HEAD.FIELDLENTYPE       BYTE
*  *-----------------------------------------------------------------
*  |  Result table
*  *-----------------------------------------------------------------
*     HEAD
*       ∟TYPE|KEY|BUKRS|VBELN
*         A    01  2A01  1234567890
*         A    01  2A01  9876543210
*
*  *------------------------------------------------------------------
*  | ②Complex deep file source data:
*  *------------------------------------------------------------------
*     A012A01
*     A0200010ABCDEF
*     A03TEXT
*     A012A01
*     A0200010HIGKLM
*     A03TEXT1
*     A03TEXT2
*     A0200020NOPQRS
*  *------------------------------------------------------------------
*  |  Convert rule
*  *------------------------------------------------------------------
*    [PARAM]           |     [VALUE]
*     STRUCTURE               HEAD,ITEMS,DETAILS
*     KEYFNAME                KEY
*     HEAD.FIELDNAMES         TYPE,KEY,BUKRS
*     HEAD.FIELDLEN           1,2,4
*     HEAD.FIELDLENTYPE       BYTE
*     HEAD.KEYVALUE           01
*     HEAD.PARENT             ROOT
*     ITEMS.FIELDNAMES        TYPE,KEY,POSNR,MATNR
*     ITEMS.FIELDLEN          1,2,5,6
*     ITEMS.FIELDLENTYPE      BYTE
*     ITEMS.KEYVALUE          02
*     ITEMS.PARENT            HEAD
*     DETAILS.FIELDNAMES      TYPE,KEY,DESCRIP
*     DETAILS.FIELDLEN        1,2,20
*     DETAILS.FIELDLENTYPE    BYTE
*     DETAILS.KEYVALUE        03
*     DETAILS.PARENT          ITEMS
*  *-----------------------------------------------------------------
*  |  Result table
*  *-----------------------------------------------------------------
*     HEAD
*       ∟TYPE|KEY|BUKRS|ITEMS
*       | A    01  2A01   |
*       |                 ∟TYPE|KEY|POSNR|MATNR|DETAILS
*       |                   A    02  00010 ABCDEF   |
*       |                                           ∟TYPE|KEY|DESCRIP
*       |                                             A    03  TEXT
*       ∟TYPE|KEY|BUKRS|ITEMS
*         A    01  2A01   |
*                         ∟TYPE|KEY|POSNR|MATNR|DETAILS
*                         | A    02  00010 HIGKLM   |
*                         |                         ∟TYPE|KEY|DESCRIP
*                         |                         | A    03  TEXT1
*                         |                         ∟TYPE|KEY|DESCRIP
*                         |                           A    03  TEXT2
*                         ∟TYPE|KEY|POSNR|MATNR|DETAILS
*                           A    02  00010 NOPQRS
**********************************************************************
    DATA:
      lt_struc_name TYPE STANDARD TABLE OF string,
      lt_fnames     TYPE STANDARD TABLE OF string,
      lt_flen       TYPE STANDARD TABLE OF string,
      lv_param      TYPE string.

    DATA:
      ls_error  TYPE bapiret2,
      lo_result TYPE REF TO data.

    DATA:
      lt_components TYPE abap_component_tab,
      lo_strucdescr TYPE REF TO cl_abap_structdescr,
      lo_tabledescr TYPE REF TO cl_abap_tabledescr,
      lo_struc      TYPE REF TO data,
      lo_table      TYPE REF TO data.

    DATA:
      ls_line_type TYPE zprbcs_convert_line_type.

    DATA:
      ls_compoments       TYPE abap_componentdescr.

    FIELD-SYMBOLS:
      <fs_table> TYPE STANDARD TABLE.

*   <Structure>
    lv_param = 'STRUCTURE'.

    READ TABLE it_convert_rule INTO DATA(ls_convert_struc)
      WITH KEY param = lv_param.

    IF sy-subrc <> 0.
      ls_error-type    = 'E'.
      ls_error-message = 'Parameter "STRUCTURE" is requeried.'(001).
      APPEND ls_error TO et_error.
      RAISE convert_failed.
    ELSE.
      SPLIT ls_convert_struc-value AT ',' INTO TABLE mt_struc_name.

      LOOP AT mt_struc_name INTO DATA(ls_struc_name).
*       Recursively generated structure
        build_component(
          EXPORTING
            it_source_data  = it_source_data
            it_convert_rule = it_convert_rule
            iv_strucname    = ls_struc_name
          CHANGING
            ct_components   = lt_components
            ct_error        = et_error
         ).

        TRY.
*           Get line type
            CALL METHOD cl_abap_structdescr=>create
              EXPORTING
                p_components = lt_components
              RECEIVING
                p_result     = lo_strucdescr.

            ls_line_type-name = ls_struc_name.
            ls_line_type-type = lo_strucdescr.
            APPEND ls_line_type TO mt_line_type.
            CLEAR ls_line_type.

            TRY.
*               Get table type
                CALL METHOD cl_abap_tabledescr=>create
                  EXPORTING
                    p_line_type = lo_strucdescr
                  RECEIVING
                    p_result    = lo_tabledescr.

*               Build Final Structure
                ls_compoments-name = ls_struc_name.
                ls_compoments-type ?= lo_tabledescr.
                APPEND ls_compoments TO mt_final_components.
              CATCH cx_sy_table_creation INTO DATA(lo_excep_table_creation).
                ls_error-type    = 'E'.
                ls_error-message = lo_excep_table_creation->get_text( ).
                APPEND ls_error TO et_error.
                RAISE convert_failed.
            ENDTRY.
          CATCH cx_sy_struct_creation INTO DATA(lo_excep_struct_creation).
            ls_error-type    = 'E'.
            ls_error-message = lo_excep_struct_creation->get_text( ).
            APPEND ls_error TO et_error.
            RAISE convert_failed.
        ENDTRY.

        CLEAR:
          ls_compoments,
          lt_components.
      ENDLOOP.
    ENDIF.

*   Create Final Table and Structure
    TRY.
*       Get line type
        CALL METHOD cl_abap_structdescr=>create
          EXPORTING
            p_components = mt_final_components
          RECEIVING
            p_result     = lo_strucdescr.

        CREATE DATA lo_struc  TYPE HANDLE lo_strucdescr.
        ASSIGN lo_struc->* TO FIELD-SYMBOL(<fs_struc>).

        CLEAR mt_struc_name .
        SPLIT ls_convert_struc-value AT ',' INTO TABLE mt_struc_name.

        LOOP AT it_source_data INTO DATA(ls_source_data).
*         Mapping file data to targer structure fileds
          fill_line(
            EXPORTING
              is_source_data  = ls_source_data
              it_convert_rule = it_convert_rule
            CHANGING
              cs_struc        = <fs_struc>
              ct_error        = et_error
           ).

          IF et_error IS NOT INITIAL.
            RAISE convert_failed.
          ENDIF.
        ENDLOOP.

*       Append residual data to result table
        LOOP AT mt_line INTO DATA(ls_line).
          ASSIGN COMPONENT ls_line-name OF STRUCTURE <fs_struc> TO <fs_table>.
          ASSIGN COMPONENT 'LINE' OF STRUCTURE ls_line TO FIELD-SYMBOL(<fs_ref_line>).
          ASSIGN <fs_ref_line>->* TO FIELD-SYMBOL(<fs_line>).
          APPEND <fs_line> TO <fs_table>.

          DELETE TABLE mt_line FROM ls_line.
        ENDLOOP.

        CREATE DATA es_result TYPE HANDLE lo_strucdescr.
        ASSIGN es_result->* TO FIELD-SYMBOL(<fs_result>).
        <fs_result> = <fs_struc>.

      CATCH cx_sy_struct_creation INTO lo_excep_struct_creation.
        ls_error-type    = 'E'.
        ls_error-message = lo_excep_struct_creation->get_text( ).
        APPEND ls_error TO et_error.
        RETURN.
    ENDTRY.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>FILL_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SOURCE_DATA                 TYPE        TY_SOURCE_DATA
* | [--->] IT_CONVERT_RULE                TYPE        TT_CONVERT_RULE
* | [<-->] CS_STRUC                       TYPE        ANY
* | [<-->] CT_ERROR                       TYPE        BAPIRET2_T
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD fill_line.
    DATA:
      ls_error           TYPE bapiret2,
      lv_param           TYPE string,
      lt_fnames          TYPE STANDARD TABLE OF string,
      lt_flen            TYPE STANDARD TABLE OF string,
      lt_sep_field_value TYPE STANDARD TABLE OF string,
      lv_source_data     TYPE string,
      lv_field_value     TYPE string,
      lv_lengh_type      TYPE string,
      lv_strat_offset    TYPE i,
      lv_single_value    TYPE string,
      lv_single_length   TYPE i,
      lv_length_sum      TYPE i,
      lv_tabix           TYPE sy-tabix,
      lv_mapped          TYPE flag.

    DATA:
      lo_data  TYPE REF TO data,
      lo_struc TYPE REF TO data,
      ls_line  TYPE ty_line.

    FIELD-SYMBOLS:
      <fs_table> TYPE STANDARD TABLE.

**********************************************************************
*   Determine the type of the data in the row based on the key value
**********************************************************************
    LOOP AT mt_struc_name INTO DATA(ls_struc_name).

      lv_source_data = is_source_data-data.

      lv_param = 'KEYFNAME'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_key)
        WITH KEY param = lv_param.

*     <Structure>.FIELDNAMES
      lv_param = ls_struc_name && '.FIELDNAMES'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_fnames)
        WITH KEY param = lv_param.

      SPLIT ls_convert_fnames-value AT ',' INTO TABLE lt_fnames.

*     <Structure>.FIELDLEN
      lv_param = ls_struc_name && '.FIELDLEN'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_flen)
        WITH KEY param = lv_param.

*     <Structure>.FIELDLENTYPE
      lv_param = ls_struc_name && '.FIELDLENTYPE'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_flentype)
        WITH KEY param = lv_param.

*     <Structure>.FIELDSEPARATOR
      lv_param = ls_struc_name && '.FIELDSEPARATOR'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_fsep)
        WITH KEY param = lv_param.

**********************************************************************
*     Parsing by fixed length
**********************************************************************
      IF ls_convert_flen IS NOT INITIAL.
        SPLIT ls_convert_flen-value AT ',' INTO TABLE lt_flen.

        LOOP AT lt_flen INTO DATA(ls_flen).
          DO.
            TRY .
                lv_single_value = lv_source_data+0(1).

                IF ls_convert_flentype-value = 'BYTE'.
                  lv_single_length = cl_abap_list_utilities=>dynamic_output_length( lv_single_value ).
                ELSE.
                  lv_single_length = strlen( lv_single_value ).
                ENDIF.

                lv_length_sum = lv_length_sum + lv_single_length.

                IF lv_length_sum > ls_flen.
                  lv_field_value = lv_field_value && ` `.
                  APPEND lv_field_value TO lt_sep_field_value.

                  CLEAR:
                    lv_field_value,
                    lv_length_sum.

                  SHIFT lv_source_data BY 1 PLACES LEFT.
                  lv_source_data = ` ` && lv_source_data.

                  EXIT.
                ENDIF.

                IF lv_length_sum = ls_flen.
                  lv_field_value = lv_field_value && lv_single_value.
                  APPEND lv_field_value TO lt_sep_field_value.

                  CLEAR:
                    lv_field_value,
                    lv_length_sum.

                  SHIFT lv_source_data BY 1 PLACES LEFT.

                  EXIT.
                ENDIF.

                IF lv_length_sum < ls_flen..
                  lv_field_value = lv_field_value && lv_single_value.
                  SHIFT lv_source_data BY 1 PLACES LEFT.
                ENDIF.
              CATCH cx_sy_range_out_of_bounds.
                APPEND lv_field_value TO lt_sep_field_value.

                CLEAR:
                    lv_field_value,
                    lv_length_sum.

                EXIT.
            ENDTRY.
          ENDDO.
        ENDLOOP.
      ENDIF.

**********************************************************************
*     Parsing by separator
**********************************************************************
      IF ls_convert_fsep IS NOT INITIAL.
        SPLIT lv_source_data AT ls_convert_fsep-value INTO TABLE lt_sep_field_value.
      ENDIF.

**********************************************************************
*     IF defined the KEYFNAME attribute
**********************************************************************
      IF ls_convert_key-value IS NOT INITIAL.
*       Get key field index
        READ TABLE lt_fnames TRANSPORTING NO FIELDS
          WITH KEY table_line = ls_convert_key-value.

*       Get key field index value
        READ TABLE lt_sep_field_value INTO lv_field_value INDEX sy-tabix.

*       <Structure>.KEYVALUE
        lv_param = ls_struc_name && '.KEYVALUE'.

*       Get defined key value
        READ TABLE it_convert_rule INTO DATA(ls_convert_keyvalue)
          WITH KEY param = lv_param.

*       Check key value is same
        IF lv_field_value = ls_convert_keyvalue-value.
          lv_mapped = abap_true.

          READ TABLE mt_line INTO ls_line
            WITH KEY name = ls_struc_name.
*         Means here is new line and has a old line
          IF sy-subrc = 0.
            ASSIGN COMPONENT ls_struc_name OF STRUCTURE cs_struc TO <fs_table>.
            ASSIGN COMPONENT 'LINE' OF STRUCTURE ls_line TO FIELD-SYMBOL(<fs_ref_line>).
            ASSIGN <fs_ref_line>->* TO FIELD-SYMBOL(<fs_line>).
            APPEND <fs_line> TO <fs_table>.

            DELETE mt_line WHERE name = ls_struc_name.

*           Add line to global memory
            add_data_to_mt_line(
              EXPORTING
                iv_struc_name      = ls_struc_name
                it_sep_field_value = lt_sep_field_value
             ).
          ELSE.
            READ TABLE mt_final_components TRANSPORTING NO FIELDS
              WITH KEY name = ls_struc_name.
*           Means here is new line and it's first line
            IF sy-subrc = 0.

*             Add line to global memory
              add_data_to_mt_line(
                EXPORTING
                  iv_struc_name      = ls_struc_name
                  it_sep_field_value = lt_sep_field_value
               ).

*           Means here is a child line
            ELSE.

*             Update the fields of the corresponding node
              update_child_to_mt_line(
                EXPORTING
                  iv_struc_name      = ls_struc_name
                  it_sep_field_value = lt_sep_field_value
                  it_convert_rule    = it_convert_rule
               ).
            ENDIF.
          ENDIF.
        ELSE.
          CLEAR:
            lt_sep_field_value,
            lv_field_value.
        ENDIF.

**********************************************************************
*     If not defined KEY attribute
**********************************************************************
      ELSE.
        lv_mapped = abap_true.

        ASSIGN COMPONENT 1 OF STRUCTURE cs_struc TO <fs_table>.

        READ TABLE mt_line_type INTO DATA(ls_line_type)
          WITH KEY name = ls_struc_name.

        CREATE DATA lo_struc TYPE HANDLE ls_line_type-type.
        ASSIGN lo_struc->* TO FIELD-SYMBOL(<fs_new_struc>).

        LOOP AT lt_sep_field_value INTO DATA(ls_field_value).
          ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_new_struc> TO FIELD-SYMBOL(<fs_field_value>).
          IF <fs_field_value> IS ASSIGNED.
            <fs_field_value> = ls_field_value.
          ENDIF.

          UNASSIGN <fs_field_value>.
        ENDLOOP.

        APPEND <fs_new_struc> TO <fs_table>.
      ENDIF.

      IF lv_mapped = abap_true.
        RETURN.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>UPDATE_CHILD_TO_MT_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_STRUC_NAME                  TYPE        STRING
* | [--->] IT_SEP_FIELD_VALUE             TYPE        TT_STRING
* | [--->] IT_CONVERT_RULE                TYPE        TT_CONVERT_RULE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD update_child_to_mt_line.
    DATA:
      lv_param       TYPE string,
      lv_struc_name  TYPE string,
      lv_start_index TYPE sy-index,
      lt_parent_list TYPE STANDARD TABLE OF string.

    DATA:
      lo_struc     TYPE REF TO data,
      lt_table_ref TYPE REF TO data.

    FIELD-SYMBOLS:
      <fs_result_table> TYPE STANDARD TABLE.

    lv_struc_name = iv_struc_name.

    APPEND lv_struc_name TO lt_parent_list.

**********************************************************************
*   Find parents list
**********************************************************************
    DO.
      lv_param = lv_struc_name && '.PARENT'.

      READ TABLE it_convert_rule INTO DATA(ls_convert_parent)
        WITH KEY param = lv_param.
      IF sy-subrc = 0.
        IF ls_convert_parent-value <> 'ROOT'.
          INSERT ls_convert_parent-value INTO lt_parent_list INDEX 1.
        ENDIF.

        READ TABLE mt_final_components TRANSPORTING NO FIELDS
          WITH KEY name = ls_convert_parent-value.
        IF sy-subrc <> 0.
          lv_struc_name = ls_convert_parent-value.
        ELSE.
          EXIT.
        ENDIF.
      ELSE.
        EXIT.
      ENDIF.
    ENDDO.

    READ TABLE lt_parent_list INTO DATA(ls_parent_top) INDEX 1.

    READ TABLE mt_line INTO DATA(ls_line)
      WITH KEY name = ls_parent_top.

    ASSIGN COMPONENT 'LINE' OF STRUCTURE ls_line TO FIELD-SYMBOL(<fs_ref_line>).
    ASSIGN <fs_ref_line>->* TO FIELD-SYMBOL(<fs_line>).

    IF iv_struc_name <> ls_parent_top.
      DELETE lt_parent_list INDEX 1.

*     Update child note fields value
      update_target_child_table(
        EXPORTING
          iv_struc_name      = iv_struc_name
          it_sep_field_value = it_sep_field_value
        CHANGING
          ct_line            = <fs_line>
          ct_parent_list     = lt_parent_list
      ).
    ENDIF.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZPRBCCL_CONVERT_FILE2TABLE=>UPDATE_TARGET_CHILD_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_STRUC_NAME                  TYPE        STRING
* | [--->] IT_SEP_FIELD_VALUE             TYPE        TT_STRING
* | [<-->] CT_PARENT_LIST                 TYPE        TT_STRING
* | [<-->] CT_LINE                        TYPE        ANY
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD update_target_child_table.
    FIELD-SYMBOLS:
      <fs_table>  TYPE STANDARD TABLE,
      <fs_result> TYPE STANDARD TABLE.

    DATA:
      lo_table_ref TYPE REF TO data,
      lo_struc     TYPE REF TO data,
      lv_lines     TYPE i.

    DATA:
      lo_tabledescr TYPE REF TO cl_abap_tabledescr,
      lo_table      TYPE REF TO data.

    READ TABLE ct_parent_list INTO DATA(ls_parent_list) INDEX 1.
    IF sy-subrc = 0.
      ASSIGN COMPONENT ls_parent_list OF STRUCTURE ct_line TO <fs_table>.

      lv_lines = lines( <fs_table> ).
**********************************************************************
*     If filed name matched,append data to this node
**********************************************************************
      IF iv_struc_name = ls_parent_list.
        READ TABLE mt_line_type INTO DATA(ls_line_type)
          WITH KEY name = iv_struc_name.

        CREATE DATA lo_struc TYPE HANDLE ls_line_type-type.
        ASSIGN lo_struc->* TO FIELD-SYMBOL(<fs_new_struc>).

        LOOP AT it_sep_field_value INTO DATA(ls_field_value).
          ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_new_struc> TO FIELD-SYMBOL(<fs_field_value>).
          IF <fs_field_value> IS ASSIGNED.
            <fs_field_value> = ls_field_value.
          ENDIF.

          UNASSIGN <fs_field_value>.
        ENDLOOP.

        APPEND <fs_new_struc> TO <fs_table>.
        RETURN.
**********************************************************************
*     If not matched,Recursively search until the match is successful
**********************************************************************
      ELSE.
        DELETE ct_parent_list INDEX 1.

        READ TABLE <fs_table> ASSIGNING FIELD-SYMBOL(<fs_last_line>) INDEX lv_lines.

*       Update child note fields value
        update_target_child_table(
          EXPORTING
            iv_struc_name      = iv_struc_name
            it_sep_field_value = it_sep_field_value
          CHANGING
            ct_line            = <fs_last_line>
            ct_parent_list     = ct_parent_list
        ).
      ENDIF.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

测试程序demo源码:

*&---------------------------------------------------------------------*
*& Report ZPRTEST_FOR_DEEPFILE
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zprtest_for_deepfile.

TYPES:
  BEGIN OF ty_details,
    type TYPE string,
    key  TYPE string,
    text TYPE string,
  END OF ty_details,
  tt_details TYPE STANDARD TABLE OF ty_details WITH NON-UNIQUE EMPTY KEY.

TYPES:
  BEGIN OF ty_items,
    type    TYPE string,
    key     TYPE string,
    posnr   TYPE string,
    matnr   TYPE string,
    details TYPE tt_details,
  END OF ty_items,
  tt_items TYPE STANDARD TABLE OF ty_items WITH NON-UNIQUE EMPTY KEY,

  BEGIN OF ty_head,
    type  TYPE string,
    key   TYPE string,
    bukrs TYPE string,
    vbeln TYPE string,
    items TYPE tt_items,
  END OF ty_head,
  tt_head TYPE STANDARD TABLE OF ty_head WITH NON-UNIQUE EMPTY KEY,

  BEGIN OF ty_data,
    head TYPE tt_head,
  END OF ty_data.

TYPES:
  BEGIN OF ty_source_data,
    data TYPE string,
  END OF ty_source_data,
  tt_source_data TYPE STANDARD TABLE OF ty_source_data,

  BEGIN OF ty_convert_rule,
    param TYPE string,
    value TYPE string,
  END OF ty_convert_rule,
  tt_convert_rule TYPE STANDARD TABLE OF ty_convert_rule.

DATA:
  lt_source_data  TYPE tt_source_data,
  lt_convert_rule TYPE tt_convert_rule,
  ls_result       TYPE REF TO data,
  lt_error        TYPE bapiret2_t.

DATA:
  lt_data TYPE ty_data.

FIELD-SYMBOLS:
  <fs_result> TYPE any.

lt_source_data  = VALUE #(
                  ( data = 'A012A010123456789' )
                  ( data = 'A0200010ABCDEFGHI12345678' )
                  ( data = 'A03TEXT' )
                  ( data = 'A012A010123456789' )
                  ( data = 'A0200010ABCDEFGHI12345678' )
                  ( data = 'A03TEXT1' )
                  ( data = 'A03TEXT2' )
                  ( data = 'A0200020ABCDEFGHI12345678' )
                ).

*正常解析
lt_convert_rule = VALUE #(
                  ( param = 'STRUCTURE'            value = 'HEAD,ITEMS,DETAILS' )
                  ( param = 'KEYFNAME'             value = 'KEY' )
                  ( param = 'HEAD.FIELDNAMES'      value = 'TYPE,KEY,BUKRS,VBELN' )
                  ( param = 'HEAD.FIELDLEN'        value = '1,2,4,10' )
                  ( param = 'HEAD.FIELDLENTYPE'    value = 'BYTE' )
                  ( param = 'HEAD.KEYVALUE'        value = '01' )
                  ( param = 'HEAD.PARENT'          value = 'ROOT' )

                  ( param = 'ITEMS.FIELDNAMES'     value = 'TYPE,KEY,POSNR,MATNR' )
                  ( param = 'ITEMS.FIELDLEN'       value = '1,2,6,18' )
                  ( param = 'ITEMS.FIELDLENTYPE'   value = 'BYTE' )
                  ( param = 'ITEMS.KEYVALUE'       value = '02' )
                  ( param = 'ITEMS.PARENT'         value = 'HEAD' )

                  ( param = 'DETAILS.FIELDNAMES'   value = 'TYPE,KEY,DESCRIP' )
                  ( param = 'DETAILS.FIELDLEN'     value = '1,2,20' )
                  ( param = 'DETAILS.FIELDLENTYPE' value = 'BYTE' )
                  ( param = 'DETAILS.KEYVALUE'     value = '03' )
                  ( param = 'DETAILS.PARENT'       value = 'ITEMS' )
                ).

*将item和details设为平级,位于head节点下
*lt_convert_rule = VALUE #(
*                  ( param = 'STRUCTURE'            value = 'HEAD,ITEMS,DETAILS' )
*                  ( param = 'KEYFNAME'             value = 'KEY' )
*                  ( param = 'HEAD.FIELDNAMES'      value = 'TYPE,KEY,BUKRS,VBELN' )
*                  ( param = 'HEAD.FIELDLEN'        value = '1,2,4,10' )
*                  ( param = 'HEAD.FIELDLENTYPE'    value = 'BYTE' )
*                  ( param = 'HEAD.KEYVALUE'        value = '01' )
*                  ( param = 'HEAD.PARENT'          value = 'ROOT' )
*
*                  ( param = 'ITEMS.FIELDNAMES'     value = 'TYPE,KEY,POSNR,MATNR' )
*                  ( param = 'ITEMS.FIELDLEN'       value = '1,2,6,18' )
*                  ( param = 'ITEMS.FIELDLENTYPE'   value = 'BYTE' )
*                  ( param = 'ITEMS.KEYVALUE'       value = '02' )
*                  ( param = 'ITEMS.PARENT'         value = 'HEAD' )
*
*                  ( param = 'DETAILS.FIELDNAMES'   value = 'TYPE,KEY,DESCRIP' )
*                  ( param = 'DETAILS.FIELDLEN'     value = '1,2,20' )
*                  ( param = 'DETAILS.FIELDLENTYPE' value = 'BYTE' )
*                  ( param = 'DETAILS.KEYVALUE'     value = '03' )
*                  ( param = 'DETAILS.PARENT'       value = 'HEAD' )
*                  ).

*只解析head数据
*lt_convert_rule = VALUE #(
*                  ( param = 'STRUCTURE'            value = 'HEAD' )
*                  ( param = 'KEYFNAME'             value = 'KEY' )
*                  ( param = 'HEAD.FIELDNAMES'      value = 'TYPE,KEY,BUKRS,VBELN' )
*                  ( param = 'HEAD.FIELDLEN'        value = '1,2,4,10' )
*                  ( param = 'HEAD.FIELDLENTYPE'    value = 'BYTE' )
*                  ( param = 'HEAD.KEYVALUE'        value = '01' )
*                  ( param = 'HEAD.PARENT'          value = 'ROOT' )
*                   ).

zprbccl_convert_file2table=>convert_file2table(
  EXPORTING
    it_source_data = lt_source_data
    it_convert_rule = lt_convert_rule
  IMPORTING
    es_result = ls_result
    et_error = lt_error
 ).

ASSIGN ls_result->* TO <fs_result>.

*lt_data = <fs_result>.

BREAK-POINT.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1042733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何试用 Vectorizer.AI 将位图转换为矢量图

Vectorizer.AI 是一个使用人工智能技术将位图转换为矢量图的在线工具。它支持 JPEG、PNG、BMP 和 GIF 格式的位图&#xff0c;最大像素为 2 万像素&#xff0c;最大文件大小为 30 MB。Vectorizer.AI 目前处于测试阶段&#xff0c;完全免费使用。 要试用 Vectorizer.AI&#xf…

【微服务】spring 控制bean加载顺序使用详解

目录 一、前言 二、使用order注解控制顺序 2.1 order 注解使用示例 2.2 order注解顺序失效问题 2.2.1 order失效问题解决办法 2.3 实现Ordered接口 三、使用dependon注解控制顺序 四、AutoConfiguration注解控制bean加载顺序 4.1 AutoConfigureBefore 操作演示 4.2 A…

进程与线程的记忆方法

有很多人经常会分不清进程与线程的关系&#xff0c; 嗯。。。。。。可能只有我自己记不清吧 举个例子&#xff1a; 进程&#xff1a;登录一个qq号&#xff0c;就是一个进程。 线程&#xff1a;同时打开多个窗口聊天&#xff0c;就是多个线程。 每次记忆完&#xff0c;过了一段…

Python函数绘图与高等代数互融实例(六): 条形图|直方图|饼状图|并列柱状图

Python函数绘图与高等代数互融实例(一):正弦函数与余弦函数 Python函数绘图与高等代数互融实例(二):闪点函数 Python函数绘图与高等代数互融实例(三):设置X|Y轴|网格线 Python函数绘图与高等代数互融实例(四):设置X|Y轴参考线|参考区域 Python函数绘图与高等代数互融实例(五…

SQLAlchemy中filter函数的使用

目录 filter过滤数据 方法及使用示例 基本过滤 多个条件的过滤 模糊查询 IN查询 空值和非空值 代码演示 代码刨析 filter过滤数据 在SQLAlchemy中&#xff0c;filter 方法用于在查询中对数据进行过滤&#xff0c;以获取符合特定条件的记录。这方法允许你构建 SQL 查询中…

LeetCode-热题100-笔记-day32

二分查找 今日刷到二分查找&#xff0c;以前做过的题忘的一干二净&#xff1b;庆幸自己用新的方法做了出来两道“中等”题&#xff1b;&#xff08;我都能做出来我认为应该标“简单”&#xff09;由于之前题的难度基本在抄答案&#xff0c;所以停更几天。今天没抄答案就更新一…

OpenCV显示10bit Raw数据

参考&#xff1a;10 12 14bit图像存储格式&#xff0c;利用Opencv显示10bit Raw数据,并根据鼠标的移动显示对应位置的灰度值。其他bit位数的Raw数据方法类似。 代码实现&#xff1a; #include<opencv2/opencv.hpp> #include<iostream> #include<opencv/highgu…

asisctf 2023 web hello wp

hello 开题&#xff0c;直接给了源码。 <?php /* Read /next.txt Hint for beginners: read curls manpage. */ highlight_file(__FILE__); $url file:///hi.txt; if(array_key_exists(x, $_GET) &&!str_contains(strtolower($_GET[x]),file) && !str_c…

节日灯饰灯串灯出口欧洲CE认证办理

灯串&#xff08;灯带&#xff09;&#xff0c;这个产品的形状就象一根带子一样&#xff0c;再加上产品的主要原件就是LED&#xff0c;因此叫做灯串或者灯带。2022年&#xff0c;我国灯具及相关配件产品出口总额超过460亿美元。其中北美是最大的出口市场。其次是欧洲市场&#…

ICML 2017: 基于卷积的Seq2Seq解决方案

一.文章概述 通常而言&#xff0c;Seq2Seq解决方案一般都采用循环神经网络&#xff0c;但在本文&#xff0c;作者提出了基于卷积神经网络的解决方案ConvS2S。基于卷积神经网络的方案有两大优势&#xff1a;计算并行化更高&#xff0c;优化更容易&#xff08;非线性的数量是固定…

AndroidStudio无法查看Compose重组次数?

印象中是一开始使用AndroidStudio LayoutInspector想查看Compose重组次数的时候&#xff0c;一开始折腾了下后来忘了这茬事了&#xff0c;最近&#x1fa9c;到期了&#xff0c;家里又换了台新的mac mini又看到这个问题&#x1f60a;&#xff0c;就想着给大家整理了一下解决方法…

Python+requests+unittest+excel实现接口自动化测试框架

一、框架结构&#xff1a; 工程目录 二、Case文件设计 三、基础包 base 3.1 封装get/post请求&#xff08;runmethon.py&#xff09; 1 import requests2 import json3 class RunMethod:4 def post_main(self,url,data,headerNone):5 res None6 if heade…

win10,WSL的Ubuntu配python3.7手记

1.装linux 先在windows上安装WSL版本的Ubuntu Windows10系统安装Ubuntu子系统_哔哩哔哩_bilibili &#xff08;WSL2什么的一直没搞清楚&#xff09; 图形界面会出一些问题&#xff0c;注意勾选ccsm出的界面设置 win10安装Ubuntu16.04子系统&#xff0c;并开启桌面环境_win…

opencv: 解决保存视频失败的问题

摘要&#xff1a;opencv能读取视频&#xff0c;但保存视频时报错。 一、首先要确保已经下载了openh264.dll文件&#xff0c;否则保存的视频无法打开&#xff0c;详细可以浏览这个&#xff1a;opencv&#xff1a;保存视频。 二、保存视频时出现一下问题&#xff1a; OpenCV:…

自学Mysql调优笔记

Mysql性能调优学习 预计十天完成14/day 1. 存储引擎 存储引擎是基于表的&#xff0c;而不是基于库的 SHOW ENGINES --展示所有存储引擎1.1 InnoDB DML操作遵循ACID模型&#xff0c;支持事务。 行鸡锁&#xff0c;提供并发访问性能。 支持外键约束&#xff0c;保证数据完…

赢麻了!smardaten闷声干大事,竟然用无代码开发了复杂小程序!

本文目录 一、【前言】二、移动端项目实战&#xff1a;关爱云服务平台2.1 项目背景2.2 6大场景功能拆解&#xff08;1&#xff09;场景1-首页&#xff08;2&#xff09;场景2-找活动&#xff08;3&#xff09;场景3-找组织&#xff08;4&#xff09;场景4-找服务&#xff08;5&…

自学网络安全———(黑客技术)

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…

电压放大器在无损探伤中的应用研究

电压放大器是一种常见的电子设备&#xff0c;其主要作用是将低电平信号转换为高电平信号。在无损探伤中&#xff0c;电压放大器被广泛应用于信号增益和分析&#xff0c;以便更好地检测表面或内部缺陷。下面安泰电子Aigtek将详细介绍电压放大器在无损探伤中的应用研究。 电压放大…

电缆桥架填充计算表

一、规范要求 1、《建筑电气与智能化通用规范》&#xff08;GB55024-2022&#xff09;6.1.2&#xff1a; 导管和电缆槽盒内配电电线的总截面面积不应超过导管或电缆槽盒内截面面积的40%&#xff1b;电缆槽盒内控制线缆的总截面面积不应超过电缆槽盒内截面面积的50%。 2、《建筑…

asp.net core automapper的使用

1.安装automapper的nuget包 AutoMapper.Extensions.Microsoft.DependencyInjection 2.创建需要映射的类和转换后的类 public class studto{public int sn { get; set; }public string name { get; set; }public string sex { get; set; }public int age { get; set; }public s…