메뉴 건너뛰기

SAP 한국 커뮤니티



FUNCTION z_xml_to_table.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     REFERENCE(IV_XML) TYPE  STRING
*"     REFERENCE(IV_ROOT_NODE_NAME) TYPE  STRING OPTIONAL
*"  EXPORTING
*"     REFERENCE(E_DATA) TYPE  ANY
*"----------------------------------------------------------------------
* XML을 입력받아 인터널 테이블 또는 스트럭처로 변환한다.
* 이름의 경우 XML은 대소문자 구분하지만 ABAP에서는 대문자로 변경하여 처리함.
* 예: <Row><col1>a</col1><col2>B<col2><Row>
* 변환: ROW[1]-COL1 = 'a', ROW[1]-COl2 = 'B'

  DATAlo_ixml           TYPE REF TO if_ixml,
        lo_stream_factory TYPE REF TO if_ixml_stream_factory,
        lo_istream        TYPE REF TO if_ixml_istream,
        lo_document       TYPE REF TO if_ixml_document,
        lo_parser         TYPE REF TO if_ixml_parser,
        lo_node           TYPE REF TO if_ixml_node,
        lo_node_coll      TYPE REF TO if_ixml_node_collection,
        lo_node_list      TYPE REF TO if_ixml_node_list,
        lo_node_iterator  TYPE REF TO if_ixml_node_iterator,
        lv_flag_to_child  TYPE flag.

  CHECKiv_xml IS NOT INITIAL.
  lo_ixml cl_ixml=>create).
  lo_stream_factory lo_ixml->create_stream_factory).
  lo_istream lo_stream_factory->create_istream_cstringstring iv_xml ).
  lo_document lo_ixml->create_document).
  lo_parser lo_ixml->create_parser(
                document       lo_document
                istream        lo_istream
                stream_factory lo_stream_factory
  ).
  lo_parser->parse).

  IF iv_root_node_name IS NOT INITIAL.
    " 시작 노드 이름(IV_ROOT_NODE_NAME) 이 있으면
    lo_node_coll lo_document->get_elements_by_tag_name(
        name      iv_root_node_name
    ).
    lo_node_iterator lo_node_coll->create_iterator).
    lv_flag_to_child ''.
  ELSE.
    " 없으면 document 의 children 으로 시작.
    lo_node_list lo_document->get_children).
    lo_node_iterator lo_node_list->create_iterator).
    lv_flag_to_child 'X'.
  ENDIF.

  PERFORM xml_to_table_recursion
          USING lo_node_iterator
                lv_flag_to_child
          CHANGING e_data.


ENDFUNCTION.

*&---------------------------------------------------------------------*
*&      Form  xml_to_table_recursion
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->IO_NODE_ITERATOR  text
*      -->IV_FLAG_TO_CHILD  text
*      <--C_DATA            text
*----------------------------------------------------------------------*
FORM xml_to_table_recursion  USING    io_node_iterator TYPE REF TO if_ixml_node_iterator
                                      iv_flag_to_child TYPE flag
                             CHANGING c_data TYPE any.
  DATAlo_node           TYPE REF TO if_ixml_node,
        lo_node_coll      TYPE REF TO if_ixml_node_collection,
        lo_node_list      TYPE REF TO if_ixml_node_list,
        lo_node_attrs     TYPE REF TO if_ixml_named_node_map,
        lo_node_iterator  TYPE REF TO if_ixml_node_iterator,
        lv_c_data_type    TYPE c,
        lv_node_type      TYPE i,
        lv_node_name      TYPE string,
        lv_node_value     TYPE string.
  FIELD-SYMBOLS<lt_data> TYPE table,
                 <ls_data> TYPE data,
                 <l_data> TYPE data.

  DESCRIBE FIELD c_data TYPE lv_c_data_type.
  IF lv_c_data_type EQ 'h'" h : Internal table , u v : structure
    " 인터널 테이블 이면 빈줄 하나 추가하여 진행한다.
    ASSIGN c_data TO <lt_data>.
    APPEND INITIAL LINE TO <lt_data> ASSIGNING <ls_data>.
  ELSE.
    ASSIGN c_data TO <ls_data>.
  ENDIF.

  DO.
    lo_node io_node_iterator->get_next).
    IF lo_node IS INITIAL.
      EXIT.
    ENDIF.

    lv_node_type lo_node->get_type).
    CASE lv_node_type.
      WHEN if_ixml_node=>co_node_element.
        " 노드 엘리먼트
        lv_node_name lo_node->get_name).
        TRANSLATE lv_node_name TO UPPER CASE" 노드 이름을 대문자로
        IF iv_flag_to_child IS NOT INITIAL" true
          ASSIGN COMPONENT lv_node_name OF STRUCTURE <ls_data> TO <l_data>.
          CHECKsy-subrc EQ 0.   " 이름이 일치하는 필드가 없으면 무시.
        ELSE.
          ASSIGN <ls_data> TO <l_data>.
        ENDIF.

        " 자식 노드
        lo_node_list lo_node->get_children).
        IF lo_node_list->get_length0.
          lo_node_iterator lo_node_list->create_iterator).
          PERFORM xml_to_table_recursion
                  USING lo_node_iterator
                        'X'
                  CHANGING <l_data>.
        ENDIF.

        " 어트리뷰트
        lo_node_attrs lo_node->get_attributes).
        IF lo_node_attrs->get_length0.
          lo_node_iterator lo_node_attrs->create_iterator).
          PERFORM xml_to_table_recursion
                  USING lo_node_iterator
                        'X'
                  CHANGING <l_data>.
        ENDIF.

      WHEN if_ixml_node=>co_node_text OR if_ixml_node=>co_node_cdata_section.
        " 텍스트 값
        lv_node_value lo_node->get_value).
        <ls_data> lv_node_value.

      WHEN if_ixml_node=>co_node_attribute.
        " 노드 어트리뷰트
        lv_node_name lo_node->get_name).
        TRANSLATE lv_node_name TO UPPER CASE" 노드 이름을 대문자로
        ASSIGN COMPONENT lv_node_name OF STRUCTURE <ls_data> TO <l_data>.
        CHECKsy-subrc EQ 0.   " 이름이 일치하는 필드가 없으면 무시.
        lv_node_value lo_node->get_value).
        <l_data> lv_node_value.

      WHEN OTHERS.
        " 기타: 무시
    ENDCASE.

  ENDDO.

ENDFORM.                    " XML_TO_TABLE_RECURSION
번호 제목 글쓴이 날짜 조회 수
107 KR_POSTCODE : 한국주소입력 Version 2.0 대략나 2021.03.31 968
106 HTTP 통신하는 로직 [3] 대략나 2016.12.20 5624
» XML 을 아밥 스트럭쳐 또는 인터널테이블로 변경시키는 로직 [1] 대략나 2016.12.20 3784
104 ALV EDIT 샘플 프로그램 sapjoy 2015.06.26 9243
103 파일 메일(e-mail) 첨부로 보내기 [2] sapjoy 2014.10.10 7171
102 데이터 이메일(e-mail) xls 파일로 보내기 [2] sapjoy 2014.10.10 6671
101 Tree ALV 샘플 [5] 양키(이경환) 2014.02.05 10502
100 Split 의 사용 [1] 양키(이경환) 2014.02.05 10624
99 소수점 뒷자리 0 제거 로직 file 양키(이경환) 2014.01.19 9420
98 10이하의 홀수 마방진 은미짱 2013.10.18 6785
97 [Module pool] Container에 webpage 넣기. [2] 냥냥 2013.03.19 11194
96 COMAPY CODE에 할당된 Fiscal variant에 대한 calendar date 변환 paran 2013.02.28 10461
95 멀 어떻게 해야 하는건질 몰라 질문 드립니다 [5] 쏠라맨 2012.10.12 11660
94 nugg 프로그램을 sap 에 생성하기.. [3] file MadMax 2012.10.11 10822
93 인터널 테이블을 사용한 구구단 출력 두가지 입니다 - WRITE, ALV 이용 [1] kofnhuge 2012.10.10 13996
92 Search For Program/Function/Table Desc&Name [8] file 초짜 2011.09.30 9828
91 스크린에서 버튼을 tree 처럼 만들기. [32] file Jenny 2011.08.11 17653
90 통화단위, krw, usd 일반 필드에 변환시 로직(소수점, 자리수) [4] sapjoy 2011.07.19 15557
89 Dynamic Select 소스 [5] 떡밥 2011.06.03 17762
88 [onepaper] 참고자료 Archiving 세팅에 필요한 파일소스입니다. [7] file 원니컴 2011.03.22 13795