‎2016 Jul 20 10:59 AM
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
‎2016 Jul 20 1:42 PM
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!
‎2016 Jul 20 11:10 AM
Hi
But which kind of crash have you?
And how have you defined l_xml_line?
Max
‎2016 Jul 20 11:55 AM
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.
‎2016 Jul 20 12:04 PM
‎2016 Jul 20 1:00 PM
Thanks for your answer.
Unfortunately the result is the same. The read dataset failed at the same line and the parse error occurs.
‎2016 Jul 20 1:13 PM
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
‎2016 Jul 20 1:42 PM
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!
‎2016 Jul 20 1:57 PM
‎2016 Jul 20 2:49 PM
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 )
‎2016 Jul 20 3:41 PM
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
‎2016 Jul 20 5:02 PM
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).
‎2016 Jul 20 5:34 PM
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)
‎2016 Jul 21 10:17 AM
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).
‎2016 Jul 21 10:32 AM
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 stringsDoes it mean, that I can`t use a table with xstring elements?
Thanks again for your help!
‎2016 Jul 21 12:06 PM
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
‎2016 Jul 21 12:13 PM
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.
‎2016 Jul 21 12:34 PM
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
‎2016 Jul 21 1:30 PM
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