Application Development 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: 

ABAP send XML to application server

Former Member
0 Kudos
1,686

Greetings!

I'm working on building xml data in ABAP report (46C) and I can build the data and send to the local PC via ws_download with no problem however I have a requirement to send the xml data to the application server via "open dataset" as we wish to run this in background via a job. The XML data is delivered however there are carriage returns at the end of lines and filler characters in the last row. Below is the code I'm using which needs help.

DATA: l_dom TYPE REF TO if_ixml_element,
                m_document TYPE REF TO if_ixml_document,
                g_ixml TYPE REF TO if_ixml,
                w_string TYPE xstring,
                w_size TYPE i,
                w_result TYPE i,
                w_line TYPE string,
                it_xml TYPE dcxmllines,
                s_xml LIKE LINE OF it_xml,
                w_rc LIKE sy-subrc.

DATA: xml TYPE dcxmllines.
DATA: rc TYPE sy-subrc,
BEGIN OF xml_tab OCCURS 0,
              d LIKE LINE OF xml,
END OF xml_tab.

DATA: wa_xmlrec LIKE LINE OF xml.

DATA v_serfile(250) TYPE c.

DATA: v_err1(40),
      v_msg1(100),
      v_strlen1 TYPE i.

*---> Convert Data to XML
  CLASS cl_ixml DEFINITION LOAD.
  g_ixml = cl_ixml=>create( ).
  CHECK NOT g_ixml IS INITIAL.
  m_document = g_ixml->create_document( ).
  CHECK NOT m_document IS INITIAL.
  WRITE: / 'Converting DATA TO DOM 1:'.
  CALL FUNCTION 'SDIXML_DATA_TO_DOM'
       EXPORTING
            name         = 'it_catalogs'
            dataobject   = it_catalogs[]
       IMPORTING
            data_as_dom  = l_dom
       CHANGING
            document     = m_document
       EXCEPTIONS
            illegal_name = 1
            OTHERS       = 2.
  IF sy-subrc = 0.
    WRITE 'Ok'.
  ELSE.
    WRITE: 'Err =',
    sy-subrc.
  ENDIF.
  CHECK NOT l_dom IS INITIAL.
  w_rc = m_document->append_child( new_child = l_dom ).
  IF w_rc IS INITIAL.
    WRITE 'Ok'.
  ELSE.
    WRITE: 'Err =',
    w_rc.
  ENDIF.
  CALL FUNCTION 'SDIXML_DOM_TO_XML'
       EXPORTING
            document      = m_document
       IMPORTING
            xml_as_string = w_string
            size          = w_size
       TABLES
            xml_as_table  = it_xml
       EXCEPTIONS
            no_document   = 1
            OTHERS        = 2.
  IF sy-subrc = 0.
    WRITE 'Ok'.
  ELSE.
    WRITE: 'Err =',
    sy-subrc.
  ENDIF.

  LOOP AT it_xml INTO xml_tab-d.
    APPEND xml_tab.
  ENDLOOP.

*--> Send XML file
  IF r_local = 'X'.
    CALL FUNCTION 'WS_DOWNLOAD'
         EXPORTING
              bin_filesize = w_size
              filename     = p_ruta
              filetype     = 'BIN'
         TABLES
              data_tab     = xml_tab
         EXCEPTIONS
              OTHERS       = 10.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

  ELSEIF r_unix = 'X'.

    v_serfile = p_upath.
    OPEN DATASET v_serfile FOR OUTPUT IN TEXT MODE.
    IF sy-subrc NE 0.
      WRITE: / 'Invalide Open: ', v_serfile.
      STOP.
    ENDIF.

    LOOP AT xml_tab.

      wa_xmlrec = xml_tab-d.
      v_strlen1 = strlen( wa_xmlrec ).
      TRANSFER wa_xmlrec TO v_serfile LENGTH v_strlen1.

    ENDLOOP.

    CLOSE DATASET v_serfile.

  ENDIF.

1 ACCEPTED SOLUTION

Sandra_Rossi
Active Contributor
0 Kudos
509

In 4.6, TRANSFER always adds a newline character when you open the dataset IN TEXT MODE.

As your XML variable is in a XSTRING, the easiest is to open the dataset IN BINARY MODE, and TRANSFER the xstring content (you may loop at XML_TAB without problem)

10 REPLIES 10

Sandra_Rossi
Active Contributor
0 Kudos
510

In 4.6, TRANSFER always adds a newline character when you open the dataset IN TEXT MODE.

As your XML variable is in a XSTRING, the easiest is to open the dataset IN BINARY MODE, and TRANSFER the xstring content (you may loop at XML_TAB without problem)

0 Kudos
509

Thank you! Both of these suggestions pretty much solved 90% of my issue. The only thing that is left to solve is for some reason the xml file delivered to the application server contains a number of NULL characters at the end of the data. Depending on the length of the xml data appears to affect how many NULL characters are outputted, almost like it's filling the last 256 bytes of unused space with NULLs. Have you encountered this before?

Below is snippet of the code used.


types: begin of ty_xml_line,
  data(256) type x,
end of ty_xml_line.

data: wa_xmlrec type ty_xml_line.

:.
open dataset v_serfile for output in binary mode.

loop at xml_tab into wa_xmlrec.
v_strlen = strlen( wa_xmlrec ).
transfer wa_xmlrec to v_serfile length v_strlen1.
endloop.

close dataset v_serfile.

0 Kudos
509

When you use STRLEN (unicode check attribute unchecked) or XSTRLEN on X variables, it always give you the full length of the variable, it does not omit the trailing null bytes as they may be real bytes.

A solution to this is to use XSTRING variables, which are of variable length (unlike X variables which have a fixed length).

0 Kudos
509

When I change the types from x to xstring in both the XML internal table and work area (below). I receive an error message on the ABAP syntax of the following.. I also had to remove the XSTRLEN statement as that was returning an unknown function error from the syntax check.

"L_XML_LINEX cannot be a table, a reference, a string or contain any of these objects


types: begin of xml_linex,
  data type xstring,
end of xml_linex.

data: l_xml_linex type xml_linex.

data begin of xml_tab occurs 0,
  d type xstring,
end of xml_tab.

:.

open dataset v_serfile for output in binary mode.

loop at xml_tab into l_xml_linex.
* v_strlen1 = xstrlen( l_xml_linex ).
transfer l_xml_linex to v_serfile.
endloop.

close dataset v_serfile.

0 Kudos
509

Just do that:

types xml_linex type xstring.
data xml_tab type standard table of xml_linex with header line.

Here I indicate a header line because you maybe use it somewhere in the code, but they should not be used anymore.

0 Kudos
509

Still the same result, numerous NULL characters at the end of the xml data in the delivered file. It appears to be still filling the balance of unused space with NULLs.

0 Kudos
509

Impossible. Please show your code.

0 Kudos
509

Sure not a problem...


types xml_linex type xstring.
data xml_tab type standard table of xml_linex with header line.

***************************************************************************
* XML Data processing
***************************************************************************
data: l_dom type ref to if_ixml_element,
                m_document type ref to if_ixml_document,
                g_ixml type ref to if_ixml,
                w_string type xstring,
                w_size type i,
                w_result type i,
                w_line type string,
                it_xml type dcxmllines,
                s_xml like line of it_xml,
                w_rc like sy-subrc.

data: xml type dcxmllines.
data: rc type sy-subrc.

class cl_ixml definition load.
g_ixml = cl_ixml=>create( ).
check not g_ixml is initial.
m_document = g_ixml->create_document( ).
check not m_document is initial.
write: / 'Converting DATA TO DOM 1:'.
call function 'SDIXML_DATA_TO_DOM'
     exporting
          name         = 'it_catalogs'
          dataobject   = it_catalogs[]
     importing
          data_as_dom  = l_dom
     changing
          document     = m_document
     exceptions
          illegal_name = 1
          others       = 2.
if sy-subrc = 0.
  write 'Ok'.
else.
  write: 'Err =',
  sy-subrc.
endif.
check not l_dom is initial.
w_rc = m_document->append_child( new_child = l_dom ).
if w_rc is initial.
  write 'Ok'.
else.
  write: 'Err =',
  w_rc.
endif.
call function 'SDIXML_DOM_TO_XML'
     exporting
          document      = m_document
     importing
          xml_as_string = w_string
          size          = w_size
     tables
          xml_as_table  = it_xml
     exceptions
          no_document   = 1
          others        = 2.
if sy-subrc = 0.
  write 'Ok'.
else.
  write: 'Err =',
  sy-subrc.
endif.
loop at it_xml into xml_tab.
  append xml_tab.
endloop.

***********************************************************************************
open dataset v_serfile for output in binary mode.

loop at xml_tab.
transfer xml_tab to v_serfile.
endloop.

close dataset v_serfile.

0 Kudos
509

In each loop at it_xml (table of X of 256 bytes), you transfer exactly 256 bytes to xml_tab (XSTRING, so each line of xml_tab is exactly 256 bytes, so you get incorrect length at the end.

SDIXML_DOM_TO_XML returns it_xml and w_string (type Xstring). I think w_string is the same content as it_xml it , but probably w_string is of the correct length, so just do that:

open dataset v_serfile for output in binary mode.
TRANSFER w_string TO v_serfile.
close dataset v_serfile.

0 Kudos
509

That worked! Thanks for the all the help!!