‎2014 Feb 12 3:41 PM
Hi, i am struggling with transferring a xml file onto application server.
MY release is 46c.
When using open-transfer-close to transfer the generated xml from an internal table,the very last record contains junk characters
(is the closing tag) (I.E. </p:FatturaElettronica>############################## ).
This issue is urgent as i cannot send the invoice xml file to client.
I hope someone can help.
Thanks.
Here is my code:
| DATA: lr_stream_factory | TYPE REF TO if_ixml_stream_factory, | |
| lr_ostream | TYPE REF TO if_ixml_ostream, | |
| lr_ostream_string | TYPE REF TO if_ixml_ostream, | |
| lr_ostream_xstring | TYPE REF TO if_ixml_ostream. |
| DATA: lt_xml | TYPE ckf_t_xml, | |
| ld_size | TYPE i, | |
| lt_xml_stru | TYPE LINE OF ckf_t_xml. |
| DATA: lr_renderer | TYPE REF TO if_ixml_renderer, | ||
| ld_rc | TYPE i. | "#EC NEEDED |
DATA xstring_xml TYPE xstring.
DATA string_xml TYPE string.
* create stream factory
lr_stream_factory = pr_ixml_factory->create_stream_factory( ).
* create output stream
lr_ostream =
| lr_stream_factory->create_ostream_itable( table = lt_xml ). |
* create renderer
lr_renderer = pr_ixml_factory->create_renderer(
ostream = lr_ostream
document = pr_dom ).
set render modus
DATA: ld_bool TYPE boolean. "#EC NEEDED
ld_bool = lr_renderer->set_normalizing( ).
* render dom into xml
ld_rc = lr_renderer->render( ).
* download to pc
ld_size = lr_ostream->get_num_written_raw( ).
OPEN DATASET pr_filename FOR OUTPUT IN BINARY MODE.
*--- Display error messages if any.
IF sy-subrc NE 0.
MESSAGE e038(zsd) WITH 'Errore apertura file'.
EXIT.
ELSE.
*---Data is downloaded to the application server file path
LOOP AT lt_xml INTO lt_xml_stru.
TRANSFER lt_xml_stru TO pr_filename.
ENDLOOP.
ENDIF.
*--Close the Application server file (Mandatory).
CLOSE DATASET pr_filename.
‎2014 Feb 12 7:57 PM
Hi Bruno,
Maybe you can use a different approach. Try to creat your xml fila as text and then convert it to xml.
The code would be something like this:
data: ixml type ref to if_ixml,
xml_document type ref to if_ixml_document.
data: lv_string type string,
lv_xstring type xstring.
* Create the header
lv_string = '<Header>'.
* Attach data from the internal table
loop at i_table.
concatenate lv_string i_table-field into lv_string.
" add elements as needed
endloop.
* Attach the footer
concatenate lv_string '</Header>' into lv_string.
* Convert string to xstring
lv_xstring = cl_proxy_service=>cstring2xstring( lv_string ).
*create ixml dom document from xml xstring
call function 'SDIXML_XML_TO_DOM'
exporting
xml = lv_xstring
importing
document = xml_document
exceptions
invalid_input = 1
others = 2.
Bernardo
‎2014 Feb 12 4:23 PM
Maybe you are trying to transfer beyond the last char of lt_xml_stru, so you could try to transfer only the char needed. I don't have the ckf_t_xml type in my system so I can't test it but if you check the lt_xml_stru lenght then you can make TRANSFER lt_xml_stru TO pr_filename LENGHT str_lenght.
Marco
‎2014 Feb 12 6:20 PM
How do i calculate the length of last record?
the internal table contains non-readable characters (it's a BIN file) and it's made out of standard
xml related function modules.
For sure , having the last record length available i could try to use it, but honestly i tried
in many different ways but couldn't solve it.
If there's a way to calculate the length that could help but i have no idea how to do it.
I saw a few post who deals with using SCMS functions module but those are not available on 46c.
I tried copying one from ecc system but still couldn't get a damn solution!!
‎2014 Feb 12 6:22 PM
Wouldn't it be easier to make a text internal table and open a file in text mode?
IS there a way to make an internal table with ascii characters so i can transfer them as text?
‎2014 Feb 12 6:31 PM
I found somewhere that: ld_size = lr_ostream->get_num_written_raw( ) gives back the exact length
of the entire xml document. Given that, how do i use it within the transfer in order to output only the
good charatcters and get rid of the junk?
‎2014 Feb 12 7:57 PM
Hi Bruno,
Maybe you can use a different approach. Try to creat your xml fila as text and then convert it to xml.
The code would be something like this:
data: ixml type ref to if_ixml,
xml_document type ref to if_ixml_document.
data: lv_string type string,
lv_xstring type xstring.
* Create the header
lv_string = '<Header>'.
* Attach data from the internal table
loop at i_table.
concatenate lv_string i_table-field into lv_string.
" add elements as needed
endloop.
* Attach the footer
concatenate lv_string '</Header>' into lv_string.
* Convert string to xstring
lv_xstring = cl_proxy_service=>cstring2xstring( lv_string ).
*create ixml dom document from xml xstring
call function 'SDIXML_XML_TO_DOM'
exporting
xml = lv_xstring
importing
document = xml_document
exceptions
invalid_input = 1
others = 2.
Bernardo
‎2014 Feb 13 9:43 AM
PRoblem solved:
i was helped from this sap documentation:
When rendering the DOM
into a table-based stream, i.e. the XML stream is "line-wrapped" into an
unstructured internal table (based on type X), it might happen, that you
encounter some data in the last filled table line which seems to be garbage. You
are right with that assumption!
In order to find out
where the correct data stream ends and where the "garbage" starts, you have to
consider the exact length of the data written to your output stream. To get that
information, you have to call the method if_ixml_ostream->get_num_written_raw(). This method will tell you how many bytes have
been filled into the table. Taking this number module your table's line-length
will give you the number of valid characters in the last table line.
So here's how your code should look like:
BAsically i had to calculate te reminder of xml_size by 256.
then when i transfer the internal table to dataset , the very last transferred record will be like
TRANSFER save_xml_stru TO pr_filename LENGTH a, where A is the reminder.