Verwendung
DATA: o_xml_doc TYPE REF TO if_ixml_document.
* Erzeugt String aus DOM-XML-Document
DATA(lv_xml_string) = lcl_xml_tool=>get_xml_string_from_xml_doc( i_dom_xml_doc = o_xml_doc ).
* Gibt rekursiv alle Nodes unterhalb übergebener Node aus
lcl_xml_tool=>print_xml( o_xml_doc->get_root_element( ) ).
Klasse
CLASS lcl_xml_tool DEFINITION.
PUBLIC SECTION.
*--------------------------------------------------------------------*
CLASS-METHODS: get_xml_string_from_xml_doc
IMPORTING
i_dom_xml_doc TYPE REF TO if_ixml_document
i_encoding TYPE string DEFAULT 'UTF-8'
RETURNING VALUE(ret_xml_str) TYPE string.
*--------------------------------------------------------------------*
CLASS-METHODS: get_node_string
IMPORTING
i_dom_xml_node TYPE REF TO if_ixml_node
i_close TYPE boolean
RETURNING VALUE(ret_string) TYPE string.
*--------------------------------------------------------------------*
CLASS-METHODS: print_xml
IMPORTING
i_dom_xml_root TYPE REF TO if_ixml_node.
*--------------------------------------------------------------------*
PRIVATE SECTION.
CONSTANTS: co_stretch_factor TYPE i VALUE 4.
ENDCLASS.
*--------------------------------------------------------------------*
CLASS lcl_xml_tool IMPLEMENTATION.
*--------------------------------------------------------------------*
* Erzeugt String aus DOM-XML-Document
*--------------------------------------------------------------------*
* -> i_dom_xml_doc - DOM-XML-Document
* -> i_encoding - XML-Encoding
* <- ret_xml_str - DOM-XML-Document als String
*--------------------------------------------------------------------*
METHOD get_xml_string_from_xml_doc.
ret_xml_str = ''.
TRY.
DATA(o_ixml) = cl_ixml=>create( ).
DATA(o_sf) = o_ixml->create_stream_factory( ).
DATA(o_encoding) = o_ixml->create_encoding( character_set = i_encoding
byte_order = if_ixml_encoding=>co_none ).
DATA: lv_xml TYPE string.
DATA(o_ostream) = o_sf->create_ostream_cstring( lv_xml ).
o_ostream->set_encoding( encoding = o_encoding ).
o_ostream->set_pretty_print( pretty_print = abap_true ).
DATA(o_render) = o_ixml->create_renderer( ostream = o_ostream
document = i_dom_xml_doc ).
* XML-String in lv_xml generieren
DATA(lv_rc) = o_render->render( ).
* Dateigröße in Bytes
DATA(lv_size) = o_ostream->get_num_written_raw( ).
* Stream schließen
o_ostream->close( ).
IF lv_rc = 0 AND lv_size > 0.
ret_xml_str = lv_xml.
ENDIF.
CATCH cx_root.
ENDTRY.
ENDMETHOD.
*--------------------------------------------------------------------*
* Erzeugt String aus Node
*--------------------------------------------------------------------*
* -> i_dom_xml_node - Node
* -> i_close - evtl. Schließen-Tag ausgeben
* <- ret_string - Node-String
*--------------------------------------------------------------------*
METHOD get_node_string.
ret_string = ''.
TRY.
CASE i_dom_xml_node->get_type( ).
* Element
WHEN if_ixml_node=>co_node_element.
DATA(o_attr) = i_dom_xml_node->get_attributes( ).
DATA: lv_attr TYPE string.
IF o_attr IS BOUND.
DATA(lv_attr_cnt) = o_attr->get_length( ).
* alle Attribute ausgeben
DO lv_attr_cnt TIMES.
DATA(o_attri_item) = o_attr->get_item( sy-index - 1 ).
* Namespace
DATA(lv_namespace) = o_attri_item->get_namespace( ).
* DATA(lv_prefix) = o_attri_item->get_namespace_prefix( ).
DATA(lv_ns_attr) = lv_namespace.
* Namespace:Attribut
IF NOT lv_ns_attr IS INITIAL.
lv_ns_attr = |{ lv_ns_attr }:{ o_attri_item->get_name( ) }|.
else.
lv_ns_attr = |{ o_attri_item->get_name( ) }|.
ENDIF.
IF lv_attr IS INITIAL.
lv_attr = |{ lv_ns_attr }="{ o_attri_item->get_value( ) }"|.
ELSE.
lv_attr = |{ lv_attr } { lv_ns_attr }="{ o_attri_item->get_value( ) }"|.
ENDIF.
ENDDO.
ENDIF.
IF i_close = abap_false.
DATA(lv_close_tag) = |>|.
* Gibt es Unterelemente zur Node?
IF i_dom_xml_node->get_first_child( ) IS INITIAL.
lv_close_tag = |/>|.
ENDIF.
IF strlen( lv_attr ) = 0.
ret_string = |<{ i_dom_xml_node->get_name( ) }{ lv_close_tag }|.
ELSE.
ret_string = |<{ i_dom_xml_node->get_name( ) } { lv_attr }{ lv_close_tag }|.
ENDIF.
ELSE.
ret_string = |</{ i_dom_xml_node->get_name( ) }>|.
ENDIF.
* Werte
WHEN if_ixml_node=>co_node_text OR if_ixml_node=>co_node_cdata_section.
ret_string = i_dom_xml_node->get_value( ).
ENDCASE.
CATCH cx_root.
ENDTRY.
ENDMETHOD.
*--------------------------------------------------------------------*
* Gibt rekursiv alle Nodes ab i_xml_root (Root) aus
*--------------------------------------------------------------------*
* -> i_dom_xml_root - Root-Node
*--------------------------------------------------------------------*
METHOD print_xml.
* Einrückung
DATA(lv_indent) = i_dom_xml_root->get_height( ) * co_stretch_factor.
WRITE: / |{ ' ' WIDTH = lv_indent }{ get_node_string( i_dom_xml_node = i_dom_xml_root
i_close = abap_false ) }|.
DATA(o_node) = i_dom_xml_root->get_first_child( ).
IF NOT o_node IS INITIAL.
* Wenn Childs vorhanden -> auflisten
WHILE NOT o_node IS INITIAL.
print_xml( o_node ).
o_node = o_node->get_next( ).
ENDWHILE.
* evtl. Schließ-Tag setzen
WRITE: / |{ ' ' WIDTH = lv_indent }{ get_node_string( i_dom_xml_node = i_dom_xml_root
i_close = abap_true ) }|.
ENDIF.
ENDMETHOD.