anchor.diff:  
   ENDCLASS.                    "lcl_user IMPLEMENTATION
   
  -*----------------------------------------------------------------------*
  -*       CLASS lcl_xml DEFINITION
  -*----------------------------------------------------------------------*
  -*
  -*----------------------------------------------------------------------*
  -*CLASS lcl_xml DEFINITION FINAL CREATE PUBLIC.
  -*
  -*  PUBLIC SECTION.
  -*    DATA: mi_xml_doc TYPE REF TO if_ixml_document.
  -*
  -*    METHODS constructor
  -*      IMPORTING iv_xml   TYPE string OPTIONAL
  -*                iv_empty TYPE sap_bool DEFAULT abap_false
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS element_add
  -*      IMPORTING ig_element TYPE data
  -*                iv_name    TYPE string OPTIONAL
  -*                ii_root    TYPE REF TO if_ixml_element OPTIONAL
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS element_read
  -*      IMPORTING ii_root    TYPE REF TO if_ixml_element OPTIONAL
  -*                iv_name    TYPE string OPTIONAL
  -*      EXPORTING ev_success TYPE abap_bool
  -*      CHANGING  cg_element TYPE data
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS structure_add
  -*      IMPORTING ig_structure TYPE data
  -*                iv_name      TYPE string OPTIONAL
  -*                ii_root      TYPE REF TO if_ixml_element OPTIONAL
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS structure_read
  -*      IMPORTING ii_root      TYPE REF TO if_ixml_element OPTIONAL
  -*                iv_name      TYPE string OPTIONAL
  -*      EXPORTING ev_success   TYPE abap_bool
  -*      CHANGING  cg_structure TYPE data
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS table_add
  -*      IMPORTING it_table  TYPE STANDARD TABLE
  -*                iv_name   TYPE string OPTIONAL
  -*                iv_stable TYPE abap_bool DEFAULT abap_false
  -*                ii_root   TYPE REF TO if_ixml_element OPTIONAL
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS table_read
  -*      IMPORTING ii_root  TYPE REF TO if_ixml_element OPTIONAL
  -*                iv_name  TYPE string OPTIONAL
  -*      CHANGING  ct_table TYPE STANDARD TABLE
  -*      RAISING   lcx_exception.
  -*
  -*    METHODS xml_render
  -*      IMPORTING iv_normalize     TYPE sap_bool DEFAULT abap_true
  -*      RETURNING VALUE(rv_string) TYPE string.
  -*
  -*    METHODS xml_element
  -*      IMPORTING iv_name           TYPE string
  -*      RETURNING VALUE(ri_element) TYPE REF TO if_ixml_element.
  -*
  -*    METHODS xml_add
  -*      IMPORTING ii_root    TYPE REF TO if_ixml_element OPTIONAL
  -*                ii_element TYPE REF TO if_ixml_element.
  -*
  -*    METHODS xml_find
  -*      IMPORTING ii_root           TYPE REF TO if_ixml_element OPTIONAL
  -*                iv_name           TYPE string
  -*      RETURNING VALUE(ri_element) TYPE REF TO if_ixml_element.
  -*
  -*  PRIVATE SECTION.
  -*    DATA: mi_ixml TYPE REF TO if_ixml,
  -*          mi_root TYPE REF TO if_ixml_element.
  -*
  -*    METHODS special_names
  -*      CHANGING cv_name TYPE string.
  -*
  -*    METHODS display_xml_error
  -*      RAISING lcx_exception.
  -*
  -*    METHODS error
  -*      IMPORTING ii_parser TYPE REF TO if_ixml_parser
  -*      RAISING   lcx_exception.
  -*
  -*ENDCLASS.                    "lcl_xml DEFINITION
  -
  -*----------------------------------------------------------------------*
  -*       CLASS lcl_xml IMPLEMENTATION
  -*----------------------------------------------------------------------*
  -*
  -*----------------------------------------------------------------------*
  -*CLASS lcl_xml IMPLEMENTATION.
  -*
  -*  METHOD xml_find.
  -*
  -*    DATA: li_root LIKE ii_root.
  -*
  -*
  -*    IF ii_root IS BOUND.
  -*      li_root = ii_root.
  -*    ELSE.
  -*      li_root = mi_root.
  -*    ENDIF.
  -*
  -*    ri_element = li_root->find_from_name( depth = 0 name = iv_name ).
  -*    IF NOT ri_element IS BOUND.
  -*      RETURN.
  -*    ENDIF.
  -*    li_root->remove_child( ri_element ).
  -*
  -*  ENDMETHOD.                    "xml_find
  -*
  -*  METHOD xml_element.
  -*
  -*    ri_element = mi_xml_doc->create_element( iv_name ).
  -*
  -*  ENDMETHOD.                    "xml_element
  -*
  -*  METHOD special_names.
  -*
  -*    IF cv_name(1) = '*'.
  -*      CONCATENATE 'STAR' cv_name+1 INTO cv_name.
  -*    ELSEIF cv_name(1) = '2'.
  -*      CONCATENATE 'TWO' cv_name+1 INTO cv_name.
  -*    ENDIF.
  -*
  -*  ENDMETHOD.                    "special_names
  -*
  -*  METHOD structure_read.
  -*
  -*    DATA: lv_name      TYPE string,
  -*          li_struct    TYPE REF TO if_ixml_element,
  -*          lo_typedescr TYPE REF TO cl_abap_typedescr,
  -*          lo_descr_ref TYPE REF TO cl_abap_structdescr.
  -*
  -*    FIELD-SYMBOLS: <lg_any>  TYPE any,
  -*                   <ls_comp> LIKE LINE OF lo_descr_ref->components.
  -*
  -*
  -*    CLEAR cg_structure.
  -*    ev_success = abap_true.
  -*
  -*    lo_descr_ref ?= cl_abap_typedescr=>describe_by_data( cg_structure ).
  -*    IF iv_name IS INITIAL.
  -*      lv_name = lo_descr_ref->get_relative_name( ).
  -*      IF lv_name IS INITIAL.
  -*        _raise 'no name, structure read'.
  -*      ENDIF.
  -*    ELSE.
  -*      lv_name = iv_name.
  -*    ENDIF.
  -*
  -*    li_struct = xml_find( ii_root = ii_root
  -*                          iv_name = lv_name ).
  -*    IF NOT li_struct IS BOUND.
  -*      ev_success = abap_false.
  -*      RETURN.
  -*    ENDIF.
  -*
  -*    LOOP AT lo_descr_ref->components ASSIGNING <ls_comp>.
  -*      ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE cg_structure TO <lg_any>.
  -*      ASSERT sy-subrc = 0.
  -*
  -*      lv_name = <ls_comp>-name.
  -*      special_names( CHANGING cv_name = lv_name ).
  -*
  -*      lo_typedescr = cl_abap_typedescr=>describe_by_data( <lg_any> ).
  -*      CASE lo_typedescr->kind.
  -*        WHEN cl_abap_typedescr=>kind_table.
  -*          table_read( EXPORTING ii_root  = li_struct
  -*                                iv_name  = lv_name
  -*                      CHANGING  ct_table = <lg_any> ).
  -*        WHEN cl_abap_typedescr=>kind_struct.
  -*          structure_read( EXPORTING ii_root      = li_struct
  -*                                    iv_name      = lv_name
  -*                          CHANGING  cg_structure = <lg_any> ).
  -*        WHEN cl_abap_typedescr=>kind_elem.
  -*          element_read( EXPORTING ii_root    = li_struct
  -*                                  iv_name    = lv_name
  -*                        CHANGING  cg_element = <lg_any> ).
  -*        WHEN cl_abap_typedescr=>kind_ref.
  -*          CONTINUE.
  -*        WHEN OTHERS.
  -*          _raise 'unknown kind, structure read'.
  -*      ENDCASE.
  -*    ENDLOOP.
  -*
  -*  ENDMETHOD.                    "structure_read
  -*
  -*  METHOD table_read.
  -*
  -*    DATA: lv_name        TYPE string,
  -*          li_root        TYPE REF TO if_ixml_element,
  -*          lv_kind        TYPE abap_typecategory,
  -*          lv_index       TYPE i,
  -*          lv_success     TYPE abap_bool,
  -*          lo_data_descr  TYPE REF TO cl_abap_datadescr,
  -*          lo_table_descr TYPE REF TO cl_abap_tabledescr.
  -*
  -*    FIELD-SYMBOLS: <lg_line> TYPE any.
  -*
  -*
  -*    CLEAR ct_table[].
  -*
  -*    lo_table_descr ?= cl_abap_typedescr=>describe_by_data( ct_table ).
  -*    lv_name = lo_table_descr->get_relative_name( ).
  -*
  -*    IF lv_name IS INITIAL.
  -*      lv_name = iv_name.
  -*    ENDIF.
  -*
  -*    IF lv_name IS INITIAL.
  -*      _raise 'no name, table read'.
  -*    ENDIF.
  -*
  -*    li_root = xml_find( ii_root   = ii_root
  -*                        iv_name   = lv_name ).
  -*    IF NOT li_root IS BOUND.
  -*      RETURN.
  -*    ENDIF.
  -*
  -*    lo_data_descr = lo_table_descr->get_table_line_type( ).
  -*    lv_kind = lo_data_descr->kind.
  -*
  -*    DO.
  -*      APPEND INITIAL LINE TO ct_table ASSIGNING <lg_line>.
  -*      CASE lv_kind.
  -*        WHEN cl_abap_typedescr=>kind_struct.
  -*          structure_read( EXPORTING ii_root    = li_root
  -*                          IMPORTING ev_success = lv_success
  -*                          CHANGING cg_structure = <lg_line> ).
  -*        WHEN cl_abap_typedescr=>kind_elem.
  -*          element_read( EXPORTING ii_root    = li_root
  -*                        IMPORTING ev_success = lv_success
  -*                        CHANGING  cg_element = <lg_line> ).
  -*        WHEN OTHERS.
  -*          _raise 'unknown kind'.
  -*      ENDCASE.
  -*
  -*      IF lv_success = abap_false.
  -*        lv_index = lines( ct_table ).
  -*        DELETE ct_table INDEX lv_index.
  -*        ASSERT sy-subrc = 0.
  -*        EXIT. " current loop
  -*      ENDIF.
  -*    ENDDO.
  -*
  -*  ENDMETHOD.                    "table_read
  -*
  -*  METHOD error.
  -*
  -*    DATA: lv_error TYPE i,
  -*          lv_txt1  TYPE string,
  -*          lv_txt2  TYPE string,
  -*          lv_txt3  TYPE string,
  -*          lv_times TYPE i,
  -*          li_error TYPE REF TO if_ixml_parse_error.
  -*
  -*
  -*    IF ii_parser->num_errors( ) <> 0.
  -*      lv_times = ii_parser->num_errors( ).
  -*      DO lv_times TIMES.
  -*        lv_error = sy-index - 1.
  -*        li_error = ii_parser->get_error( lv_error ).
  -*
  -*        lv_txt1 = li_error->get_column( ).
  -*        CONCATENATE 'Column:' lv_txt1 INTO lv_txt1.         "#EC NOTEXT
  -*        lv_txt2 = li_error->get_line( ).
  -*        CONCATENATE 'Line:' lv_txt2 INTO lv_txt2.           "#EC NOTEXT
  -*        lv_txt3 = li_error->get_reason( ).
  -*
  -*        CALL FUNCTION 'POPUP_TO_INFORM'
  -*          EXPORTING
  -*            titel = 'Error from XML parser'                 "#EC NOTEXT
  -*            txt1  = lv_txt1
  -*            txt2  = lv_txt2
  -*            txt3  = lv_txt3.
  -*      ENDDO.
  -*    ENDIF.
  -*
  -*    _raise 'Error while parsing XML'.
  -*  ENDMETHOD.                    "error
  -*
  -*  METHOD constructor.
  -*
  -*    CONSTANTS: c_version     TYPE string VALUE 'version' ##NO_TEXT,
  -*               c_abapgit_tag TYPE string VALUE 'abapGit'.
  -*
  -*    DATA: li_stream_factory TYPE REF TO if_ixml_stream_factory,
  -*          li_istream        TYPE REF TO if_ixml_istream,
  -*          li_version        TYPE REF TO if_ixml_node,
  -*          li_parser         TYPE REF TO if_ixml_parser.
  -*
  -*
  -*    mi_ixml = cl_ixml=>create( ).
  -*    mi_xml_doc = mi_ixml->create_document( ).
  -*
  -*    IF iv_xml IS SUPPLIED.
  -*      li_stream_factory = mi_ixml->create_stream_factory( ).
  -*      li_istream = li_stream_factory->create_istream_string( iv_xml ).
  -*      li_parser = mi_ixml->create_parser( stream_factory = li_stream_factory
  -*                                          istream        = li_istream
  -*                                          document       = mi_xml_doc ).
  -*      li_parser->set_normalizing( abap_false ).
  -*      IF li_parser->parse( ) <> 0.
  -*        error( li_parser ).
  -*      ENDIF.
  -*
  -*      li_istream->close( ).
  -*
  -*      mi_root = mi_xml_doc->find_from_name( depth = 0 name = c_abapgit_tag ).
  -*
  -*      li_version = mi_root->if_ixml_node~get_attributes( )->get_named_item_ns( c_version ).
  -*      IF li_version->get_value( ) <> gc_xml_version.
  -*        display_xml_error( ).
  -*      ENDIF.
  -*    ELSEIF iv_empty = abap_false.
  -*      mi_root = mi_xml_doc->create_element( c_abapgit_tag ).
  -*      mi_root->set_attribute( name = c_version value = gc_xml_version ). "#EC NOTEXT
  -*      mi_xml_doc->append_child( mi_root ).
  -*    ENDIF.
  -*  ENDMETHOD.                    "xml_root
  -*
  -*  METHOD display_xml_error.
  -*
  -*    DATA: lv_version TYPE string.
  -*
  -*
  -*    lv_version = |abapGit version: { gc_abap_version }|.
  -*
  -*    CALL FUNCTION 'POPUP_TO_INFORM'
  -*      EXPORTING
  -*        titel = 'abapGit XML version mismatch'
  -*        txt1  = 'abapGit XML version mismatch'
  -*        txt2  = 'See https://github.com/larshp/abapGit/wiki/XML-Mismatch'
  -*        txt3  = lv_version. "#EC NOTEXT
  -*
  -*    _raise 'XML error'.
  -*
  -*  ENDMETHOD.
  -*
  -*  METHOD table_add.
  -*
  -*    DATA: lv_name        TYPE string,
  -*          li_table       TYPE REF TO if_ixml_element,
  -*          lv_kind        TYPE abap_typecategory,
  -*          lo_data_descr  TYPE REF TO cl_abap_datadescr,
  -*          lo_table_descr TYPE REF TO cl_abap_tabledescr.
  -*
  -*    FIELD-SYMBOLS: <lg_line> TYPE any.
  -*
  -*
  -*    lo_table_descr ?= cl_abap_typedescr=>describe_by_data( it_table ).
  -*    lv_name = lo_table_descr->get_relative_name( ).
  -*
  -*    IF lv_name IS INITIAL.
  -*      lv_name = iv_name.
  -*    ENDIF.
  -*
  -*    IF lv_name IS INITIAL.
  -*      _raise 'no name, table add'.
  -*    ENDIF.
  -*
  -*    li_table = mi_xml_doc->create_element( lv_name ).
  -*    lo_data_descr = lo_table_descr->get_table_line_type( ).
  -*    lv_kind = lo_data_descr->kind.
  -*
  -*    LOOP AT it_table ASSIGNING <lg_line>.
  -*      CASE lv_kind.
  -*        WHEN cl_abap_typedescr=>kind_struct.
  -*          structure_add( ig_structure = <lg_line>
  -*                         ii_root      = li_table ).
  -*        WHEN cl_abap_typedescr=>kind_elem.
  -*          element_add( ig_element = <lg_line>
  -*                       ii_root    = li_table ).
  -*        WHEN OTHERS.
  -*          _raise 'unknown kind'.
  -*      ENDCASE.
  -*    ENDLOOP.
  -*
  -*    xml_add( ii_root    = ii_root
  -*             ii_element = li_table ).
  -*
  -*  ENDMETHOD.                    "table_add
  -*
  -*  METHOD xml_add.
  -*
  -*    IF ii_root IS BOUND.
  -*      ii_root->append_child( ii_element ).
  -*    ELSE.
  -*      mi_root->append_child( ii_element ).
  -*    ENDIF.
  -*
  -*  ENDMETHOD.                    "xml_add
  -*
  -*  METHOD element_add.
  -*
  -*    DATA: lo_descr   TYPE REF TO cl_abap_elemdescr,
  -*          lv_string  TYPE string,
  -*          li_element TYPE REF TO if_ixml_element,
  -*          li_text    TYPE REF TO if_ixml_text,
  -*          lv_name    TYPE string.
  -*
  -*    lo_descr ?= cl_abap_typedescr=>describe_by_data( ig_element ).
  -*
  -*    IF iv_name IS NOT INITIAL.
  -*      lv_name = iv_name.
  -*    ELSE.
  -*      lv_name = lo_descr->get_relative_name( ).
  -*      IF lv_name IS INITIAL.
  -*        _raise 'no name, element add'.
  -*      ENDIF.
  -*    ENDIF.
  -*
  -*    li_element = mi_xml_doc->create_element( lv_name ).
  -*
  -*    lv_string  = ig_element.
  -*    li_text    = mi_xml_doc->create_text( lv_string ).
  -*
  -*    li_element->append_child( li_text ).
  -*
  -*    xml_add( ii_root    = ii_root
  -*             ii_element = li_element ).
  -*
  -*  ENDMETHOD.                    "element_add
  -*
  -*  METHOD element_read.
  -*
  -*    DATA: lo_descr   TYPE REF TO cl_abap_elemdescr,
  -*          li_element TYPE REF TO if_ixml_element,
  -*          lv_name    TYPE string.
  -*
  -*
  -*    ev_success = abap_true.
  -*
  -*    lo_descr ?= cl_abap_typedescr=>describe_by_data( cg_element ).
  -*
  -*    IF iv_name IS INITIAL.
  -*      lv_name = lo_descr->get_relative_name( ).
  -*      IF lv_name IS INITIAL.
  -*        _raise 'no name, element read'.
  -*      ENDIF.
  -*    ELSE.
  -*      lv_name = iv_name.
  -*    ENDIF.
  -*
  -*    li_element = xml_find( ii_root = ii_root
  -*                           iv_name = lv_name ).
  -*    IF NOT li_element IS BOUND.
  -*      ev_success = abap_false.
  -*      RETURN.
  -*    ENDIF.
  -*
  -*    cg_element = li_element->get_value( ).
  -*
  -*  ENDMETHOD.                    "element_read
  -*
  -*  METHOD structure_add.
  -*
  -*    DATA: li_structure TYPE REF TO if_ixml_element,
  -*          lv_name      TYPE string,
  -*          lo_typedescr TYPE REF TO cl_abap_typedescr,
  -*          lo_descr     TYPE REF TO cl_abap_structdescr.
  -*
  -*    FIELD-SYMBOLS: <ls_comp> LIKE LINE OF lo_descr->components,
  -*                   <lg_any>  TYPE any.
  -*
  -*
  -*    lo_descr ?= cl_abap_typedescr=>describe_by_data( ig_structure ).
  -*
  -*    IF iv_name IS INITIAL.
  -*      lv_name = lo_descr->get_relative_name( ).
  -*      IF lv_name IS INITIAL.
  -*        _raise 'no name, structure add'.
  -*      ENDIF.
  -*    ELSE.
  -*      lv_name = iv_name.
  -*    ENDIF.
  -*    li_structure = mi_xml_doc->create_element( lv_name ).
  -*
  -*    LOOP AT lo_descr->components ASSIGNING <ls_comp>.
  -*      ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE ig_structure TO <lg_any>.
  -*      ASSERT sy-subrc = 0.
  -*
  -*      lv_name  = <ls_comp>-name.
  -*      special_names( CHANGING cv_name = lv_name ).
  -*
  -*      lo_typedescr = cl_abap_typedescr=>describe_by_data( <lg_any> ).
  -*      CASE lo_typedescr->kind.
  -*        WHEN cl_abap_typedescr=>kind_table.
  -*          table_add( it_table = <lg_any>
  -*                     iv_name  = lv_name
  -*                     ii_root  = li_structure ).
  -*        WHEN cl_abap_typedescr=>kind_struct.
  -*          structure_add( ig_structure = <lg_any>
  -*                         iv_name      = lv_name
  -*                         ii_root      = li_structure ).
  -*        WHEN cl_abap_typedescr=>kind_elem.
  -*          element_add( ig_element = <lg_any>
  -*                       iv_name    = lv_name
  -*                       ii_root    = li_structure ).
  -*        WHEN cl_abap_typedescr=>kind_ref.
  -*          CONTINUE.
  -*        WHEN OTHERS.
  -*          _raise 'unknown kind, structure add'.
  -*      ENDCASE.
  -*
  -*    ENDLOOP.
  -*
  -*    xml_add( ii_root    = ii_root
  -*             ii_element = li_structure ).
  -*
  -*  ENDMETHOD.                    "structure_to_xml
  -*
  -*  METHOD xml_render.
  -** will render to codepage UTF-16
  -*
  -*    DATA: li_ostream       TYPE REF TO if_ixml_ostream,
  -*          li_renderer      TYPE REF TO if_ixml_renderer,
  -*          li_streamfactory TYPE REF TO if_ixml_stream_factory.
  -*
  -*
  -*    li_streamfactory = mi_ixml->create_stream_factory( ).
  -*
  -*    li_ostream = li_streamfactory->create_ostream_cstring( rv_string ).
  -*
  -*    li_renderer = mi_ixml->create_renderer( ostream  = li_ostream
  -*                                            document = mi_xml_doc ).
  -*    IF iv_normalize = abap_true.
  -*      li_renderer->set_normalizing( ).
  -*    ENDIF.
  -*    li_renderer->render( ).
  -*
  -*  ENDMETHOD.                    "xml_render
  -*
  -*ENDCLASS.                    "lcl_xml IMPLEMENTATION
  -
   CLASS lcl_xml DEFINITION ABSTRACT.
   
     PUBLIC SECTION.
  
positive.code:     li_istream->close( ).
  
      li_element = mi_xml_doc->find_from_name( depth = 0 name = c_abapgit_tag ).
      li_version = li_element->if_ixml_node~get_attributes( )->get_named_item_ns( 'version' ).
      IF li_version->get_value( ) <> gc_xml_version.
        display_xml_error( ).
      ENDIF.
  
negative.code:         CALL TRANSFORMATION id
            OPTIONS value_handling = 'accept_data_loss'
            SOURCE XML mi_xml_doc
            RESULT (lt_rtab) ##NO_TEXT.
        CATCH cx_transformation_error INTO lx_error.
          lv_text = lx_error->if_message~get_text( ).
          _raise lv_text.
  