Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Transform XML-String to human readable XML-File

Former Member
0 Likes
2,206

I need to transform a XML-String as coming from a simple transformation into a human readable XML-File. That means with linebreaks and logical indenting, each line not longer than n charactors.

Example:

<one><two>text</two><three><four>text</four></three></one>

into


<one>
  <two>text</two>
  <three>
    <four>text</four>
  </three>
</one>

5 REPLIES 5
Read only

Former Member
0 Likes
1,010

Yeah I need to do the same. The "RENDER_2_STRING" method of CL_XML_DOCUMENT_BASE has a parameter for pretty printing but it doesn't appear to work - i.e. it doesn't insert CR/LF into the XML string.

Let me know if you manage to figure this one out (and vice-versa I'll let you know if I figure it out).

Thanks!

Read only

0 Likes
1,010

I wrote a method that will do this, but the method can not handle all kinds of XML-strings, but it works with most simple XML-Strings:

METHOD xml_str2table.
*** Importing
**    I_XMLSTRING type csequence
*** Returning
***   e_tab_XMLtab type table of string.         

  DATA l_cnt_length TYPE i.
  l_cnt_length = STRLEN( i_xmlstring ).
  DATA l_cnt_index TYPE i.
  DATA l_xmlline TYPE string.
  DATA l_oldchar TYPE c.
  DATA l_char TYPE c.
  DATA l_nextchar TYPE c.
  DATA l_indent TYPE i.
  DO l_cnt_length TIMES.
    l_cnt_index = sy-index - 1.
    l_char = i_xmlstring+l_cnt_index(1).
    IF sy-index < l_cnt_length.
      l_nextchar = i_xmlstring+sy-index(1).
    ENDIF.
    IF  l_char <> cl_abap_char_utilities=>newline.

      IF ( l_char = '<' AND l_nextchar = '/' ) OR
         ( l_char = '/' AND l_nextchar = '>' ).
        l_indent = l_indent - 1.
        IF l_indent < 0.
          l_indent = 0.
        ENDIF.
      ENDIF.

      IF l_char = '<' AND l_oldchar = '>'.
        APPEND l_xmlline TO e_tab_xmltab.
*      write: / l_xmlline.
        CLEAR l_xmlline.
        DO l_indent TIMES.
          CONCATENATE space space l_xmlline INTO l_xmlline SEPARATED BY space.
        ENDDO.
      ENDIF.
      if l_char <> space.
        CONCATENATE l_xmlline l_char INTO l_xmlline.
      else.
        CONCATENATE l_xmlline l_char INTO l_xmlline SEPARATED BY space.
      endif.

      IF l_char = '<' AND l_nextchar <> '/'.
        l_indent = l_indent + 1.
      ENDIF.

    ELSE.
      l_indent = 0.
      APPEND l_xmlline TO e_tab_xmltab.
*    write: / l_xmlline.
      CLEAR l_xmlline.
    ENDIF.
    l_oldchar = l_char.
  ENDDO.
  APPEND l_xmlline TO e_tab_xmltab.
*write: / l_xmlline.

ENDMETHOD. 

The second Method does the same not with an string, but with an X-String:





METHOD xml_xstr2table.
*** Importing
**    I_XMLSTRING type xsequence
*** Returning
***   e_tab_XMLtab type table of string.      

  DATA l_tmp_string TYPE string.

  DATA conv TYPE REF TO cl_abap_conv_in_ce.
  conv = cl_abap_conv_in_ce=>create(
            encoding = 'UTF-8'
            endian = 'L' ).
  conv->convert(
    EXPORTING input = i_xmlstring
    IMPORTING data = l_tmp_string ).

  e_tab_xmltab = xml_str2table( l_tmp_string ).

ENDMETHOD. 

Read only

Former Member
0 Likes
1,010

Great! Thanks Achim! Much appreciated.

Read only

Former Member
0 Likes
1,010

The problem consists in the class CL_XML_DOCUMENT_BASE RENDER method in which the method call is inserted

l_renderer-&gt; set_normalizing (is_normalizing = space).

It brings that all text in one line.  

Note 577559 - Leading blanks in XML documents

The decision in a forehead to generate a class the successor from the class cl_xml_document and to redefine the render method

Read only

0 Likes
1,010

Thank you so much for finding this!

It sees that normalization needs to be TRUE for pretty printing to work... huh.

So much better to use text (faster) than relying on IE's slow XML rendering.