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

Error while reading a xml file from the file server - Ironically gui_upload works fine

Former Member
0 Likes
5,310

Hello everyone,

I have a problem with the import of a xml file and I hope that you can help me.

My program has two options to import the xml file. The first option is via the prasentation server and works absolutely fine.

But when I want to read the file from the file server I always get an error.

For using a file from the prasentation server I use the standard "gui_upload" method. To read the file from the file server I use open, read and close dataset.

Open dataset works fine, but during the read dataset it will crash with the return code 4. The crash is at sy-tabix 180, so the the problem is not starting with the first line. Unfortunately the raw xml file can not be analyzed because all the content is in one line. But there can`t be an error in the file itself, because the other method works fine and the result ist correct.

Do you have any hints why there can be an error?

I already tried to change the input mode in the open dataset statement but with no other result.

Thanks in advance!

My code:


  OPEN DATASET g_filename FOR INPUT IN BINARY MODE.

    IF sy-subrc <> 0.

      MESSAGE text-009 TYPE 'E' DISPLAY LIKE 'I'.

    ENDIF.

    DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        MESSAGE 'Error while reading the file'(017) TYPE 'E' DISPLAY LIKE 'I'.

        EXIT.

      ENDIF.

    ENDDO.

CLOSE DATASET g_filename.
IF sy-subrc <> 0.
   MESSAGE 'Error while closing the file'(018) TYPE 'E' DISPLAY LIKE 'I'.
ENDIF.

Kind regards

Kai Schluesener

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
0 Likes
3,348

It's not an error, it's just the end of file. Just use sy-subrc <> 0 to leave the loop, not to send an error message!

17 REPLIES 17
Read only

Former Member
0 Likes
3,348

Hi

But which kind of crash have you?

And how have you defined l_xml_line?

Max

Read only

0 Likes
3,348

l_xml_line is defined like this:


TYPES: BEGIN OF t_xml_line,

  data(256) TYPE x,

  END OF _xml_line.

The definition is from the SAP document "iXML ABAP Objects Jumpstart"

iXML ABAP Objects Jumpstart - XML- Library - SAP Library



Well, maybe crash is not the right expression.

I`ll get the return code 4 which means "Data was read and the end of the file was reached or there was an attempt to read after the end of the file."

Later in my program, when I am parsing the imported xml stream, the data can not be processed.

While parsing the first line the method directly returns the error  "unexpected end-of-file".

With the file from the gui_upload everything is fine.

Read only

RaymondGiuseppi
Active Contributor
0 Likes
3,348

Try to

  • Use a DESCRIBE FIELD l_xml_line LENGTH len IN BYTE MODE
  • Add MAXIMUM LENGTH len  option to your READ DATASET statement.


Regards,

Raymond

Read only

0 Likes
3,348

Thanks for your answer.

Unfortunately the result is the same. The read dataset failed at the same line and the parse error occurs.

Read only

Former Member
0 Likes
3,348

Hi

It seems the structure you're using to upload the data is too short, try to use type XSTRING instead of X:


TYPES: BEGIN OF t_xml_line,

                    data(256) TYPE x,

                 data type xtring,

             END OF _xml_line.

Max

Read only

Sandra_Rossi
Active Contributor
0 Likes
3,349

It's not an error, it's just the end of file. Just use sy-subrc <> 0 to leave the loop, not to send an error message!

Read only

0 Likes
3,348

Especially with a TYPE 'E' DISPLAY LIKE 'I'

Read only

0 Likes
3,348

Oh sorry, the posted code was during my pitiful attempts to finde a solution

The MESSAGE statement was not in the code anymore.

The length of the structure seems to be fine also.

After some debugging I saw that the read dataset "ignores" the last line of the xml file.

Both, gui_upload and read dataset, are writing the content to the table l_xml_table, but there is one line more with gui_upload than with read dataset. (185 vs. 186 lines). I thougt that subrc 4 is set AFTER the file has been completely read.

I reviewed my code again and now I`ve added the APPEND statement when the return code is 4.


    DO.

      READ DATASET g_filename INTO l_xml_line.

      CASE sy-subrc.    

          WHEN 0.

             APPEND l_xml_line TO l_xml_table.

           WHEN 4.

               APPEND l_xml_line TO l_xml_table.

               EXIT.

           WHEN OTHERS.

               MESSAGE 'Error while reading the file'(018) TYPE 'E'.

       ENDCASE.

    ENDDO.

Now it works.

What a beginners mistake... (But I'm really still a novice in ABAP )

Read only

0 Likes
3,348

Hi

GUI_UPLOAD and OPEN DATASET work in different ways,

As Sandra says, READ DATASET returns SY-SUBRC = 4 if the end of the file is reached

Now the problem is your're using a structure shorter than the line of the file, so in the first release of your code you're missing the final part of the file:


DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        MESSAGE 'Error while reading the file'(017) TYPE 'E' DISPLAY LIKE 'I'.

        EXIT.

      ENDIF.

    ENDDO.

When READ DATA sets reaches the end of the file, the last part of the file has to be loaded, so your new version works:



DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        APPEND l_xml_line TO l_xml_table.

        EXIT.

      ENDIF.

ENDDO.

But for me it should be better to use a structure longer than actual one (as I've suggested before),, try to check this:

A)


TYPES: BEGIN OF ty_xml_line,

                 DATA(256) TYPE X,

              END   OF TY_XML_LINE.

DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        APPEND l_xml_line TO l_xml_table.

        EXIT.

      ENDIF.

ENDDO.

vs B)


TYPES: BEGIN OF ty_xml_line,

                 DATA TYPE XSTRING,

              END   OF TY_XML_LINE.

DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        EXIT.

      ENDIF.

ENDDO.

Max

Read only

0 Likes
3,348

For the case A) (resulting data object of type X), there's no need of APPEND in the case of SY-SUBRC <> 0 ; it's useful only in the case if the resulting data object is of type character.

For B), there's no need of a loop, because the whole file is read with READ DATASET, because the resulting data object is of type XSTRING (consequently, both the table of XSTRING and APPEND are useless).

Read only

0 Likes
3,348

Hi

The case A is managed in standard fm C13Z_FILE_DOWNLOAD_BINARY  (called by transaction CG3Y), try to check the code of fm C13Z_RAWDATA_READ:


CATCH SYSTEM-EXCEPTIONS OPEN_DATASET_NO_AUTHORITY = 1

                           DATASET_TOO_MANY_FILES = 2

                           OTHERS = 4.

     OPEN DATASET I_FILE FOR INPUT IN BINARY MODE.

     L_SUBRC = SY-SUBRC.

   ENDCATCH.

   IF SY-SUBRC <> 0 OR

       L_SUBRC <> 0.

     RAISE OPEN_FAILED.

   ENDIF.

* End Correction 20.11.2005 899632 *********************

* Begin Correction 21.03.2005 816266 *******************

   CATCH SYSTEM-EXCEPTIONS DATASET_READ_ERROR = 11

                           OTHERS = 12.

     DO.

     CLEAR L_LEN.

     CLEAR E_RCGREPFILE_TAB.

     READ DATASET I_FILE INTO E_RCGREPFILE_TAB-ORBLK LENGTH L_LEN.

     IF SY-SUBRC <> 0.

* Begin Correction 20.11.2005 899632 *******************

       IF L_LEN > 0.

* End Correction 20.11.2005 899632 *********************

         E_FILE_SIZE = E_FILE_SIZE + L_LEN.

         APPEND E_RCGREPFILE_TAB.

       ENDIF.

       EXIT.

     ENDIF.

     E_FILE_SIZE = E_FILE_SIZE + L_LEN.

     APPEND E_RCGREPFILE_TAB.

   ENDDO.

   ENDCATCH.

   IF SY-SUBRC > 10.

     RAISE READ_ERROR.

   ENDIF.

I know the standard is better because it's check the lenght in order to understand if it needs or doesn't need to append the data at the end, but in this case the file is loaded in a workarea type LRAW instead of X: so do you think the behavior can be different?

For the case B you're right, but I suppose he wants to use the same structure in both cases (I mean if file is on Presentaion or Application Server), so it should be appended to internal table (but I don't know the rest of his program)

Read only

0 Likes
3,348

I'm pretty sure I'm mostly right for case A, but maybe my answer is not exact for the obsolete non-Unicode systems (probably the correction was done for these systems). I have a doubt because OPEN DATASET is really tricky (one of the worst ABAP statements from my point of view). But in our answers, I think we can now consider all systems are Unicode (although it may not be true in all situations).

Read only

0 Likes
3,348

Thanks for your answers Max and Sandra. They were really interesting and helpful.

I tried your suggestions and now I have a result which seems good for me.

First I have replaced the l_xml_line and l_xml_table with a single variable from type xstring.

After my read dataset statement, the xstring contains the complete file and I`m creating the xml stream with the method create_istream_xstring instead of create_istream_itable as before.

The parsing and processing of the XML file will produce the desired result.


My read dataset statement now looks like this:

DATA: g_xstring_i      TYPE xstring,
          g_xstring_o     TYPE xstring.

DO.
     READ DATASET filename INTO g_xstring_i.
     IF SY-SUBRC = 0.
          g_xstring_o = g_xstring_i.
     ELSE.
          EXIT.
     ENDIF.
ENDDO.

I'm just still not sure whether I could assume that only one loop cycle is executed in order to read the file. Should I use a table with multiple xstring lines instead of one single xstring variable?


I also tried to use your following suggestion:

TYPES: BEGIN OF ty_xml_line,

                 DATA TYPE XSTRING,

              END   OF TY_XML_LINE.

DO.

      READ DATASET g_filename INTO l_xml_line.

      IF sy-subrc EQ 0.

        APPEND l_xml_line TO l_xml_table.

      ELSE.

        EXIT.

      ENDIF.

ENDDO.


But then I will get the following syntax error which I colund`t handle:

"L_XML_LINE" can not be a table or a reference, nor can it contain
tables, references or strings

Does it mean, that I can`t use a table with xstring elements?


Thanks again for your help!

Read only

0 Likes
3,348

Hi

If it assumes the XML file is loaded in one shot, it doesn't need the cycle

I don't know how you've defined the data, but this code works:


TYPES: BEGIN OF  TY_XML_LINE,

          DATA TYPE XSTRING,

        END  OF   TY_XML_LINE.

DATA: L_XML_LINE   TYPE TY_XML_LINE,

       L_XML_TABLE TYPE STANDARD TABLE OF TY_XML_LINE.

DATA: G_FILENAME(100) TYPE C.

OPEN DATASET G_FILENAME FOR INPUT IN BINARY MODE.

DO.

   READ DATASET G_FILENAME INTO L_XML_LINE-DATA.

   IF SY-SUBRC = 0.

     APPEND L_XML_LINE TO L_XML_TABLE.

   ENDIF.

ENDDO.

Max

Read only

0 Likes
3,348

This was my mistake:


DO.

   READ DATASET G_FILENAME INTO L_XML_LINE-DATA.

   IF SY-SUBRC = 0.

     APPEND L_XML_LINE TO L_XML_TABLE.

   ENDIF.

ENDDO.

I think that I will use this code in my programm. Thanks.

Read only

0 Likes
3,348

Hello Max,

it looks like that you have worked with some XML imports before, so maybe you can answer this 🙂

I have rebuilt Kai's problem and tried some changes in it.

Me, personally, prefer to see what kind of data will be imported. So I normally do the READ DATASET in text mode. Therefor I use a string field which gets filled. In Kai's example I get two lines, the header XML line "<?xml version="1.0" encoding="UTF-8"?>" and the data of the XML file. After that I use the CREATE_ISTREAM_STRING method for parsing into structured data.

Is there any reason why you should prefer the BINARY mode when importing XML files?


DATA: ld_input TYPE string,
          lt_input  LIKE TABLE OF ld_input.


OPEN DATASET g_filename FOR INPUT IN TEXT MODE ENCODING NON-UNICODE.


READ DATASET g_filename INTO ld_input. "l_xml_line.
   IF sy-subrc EQ 0.
      APPEND ld_input TO lt_input.

   ELSE.

      EXIT.

   ENDIF.


g_istream =  g_streamfactory->create_istream_string( string = ld_input ).

Regards

Michael

Read only

0 Likes
3,348

Hi

It depends on which kind of file you've

In this situation Kai is using X type and BYNARY mode option, so I've checked it, I mean I suppose Kai's XML file was saved as binary