XSLT: how to get source file for debugging on “call transformation”
Hi ABAP XML experts,
some days ago I started a discussion on SCN and asked about debugging in ABAP/XSLT. I am new on handling XLST by asXML, not by the ST, simple transformation. In addition to this I am not an XSLT expert. I did a lot of simple transformations but now, I had to use a real XSLT program. The SCN question of my problem wasn’t unfortunately answered. Have a short look …
I parallel I tried to find out the solution by myself of course. 😡 After some very short nights to sleep, a lot of coffee, many open books, blogs and faqs I found the easy solution. Experts will think “were is the problem ?” but I lost a lot of time for this.
To earn my badget on blogging I decided to share my new knowledge to this issue. I hope that I can help someone someday in the same situation with my blog. If so, it would be nice to give a little reply on this. This is my first blog, so I hopefully do this in a right way and you will enjoy this !
What is the matter ? Debugging on XSLT !
If you try to export complex ABAP structures via XSLT to XML, the writing of the XSLT rules is not always easy. If you have internal tables referenced into internal tables this will cost all your attention to rule this correctly. In my case the ABAP structures had in addition many content realized by dynamic structures depending on the object you want to export. 😯
After writing my XSLT, drinking the last rest of my cold coffee, putting all XLST books away from my desk, this was the time to do the first run on the transformation … and of course it failed 😥
This was the time to check the XSLT code by the XSLT debugger within transaction XSLT_TOOL. I realized that I need the “exact” source XML for debugging. There is no way (I think) on a ABAP 7.00 system to do this directly while debugging the ABAP code and jumping to the XSTL debugger.
Lets start how to solve this …
Step 1: define the ABAP side program to use a transformation.
In my case I created a little table with references to my internal ABAP tables or structures.
DATA: lt_source TYPE abap_trans_srcbind_tab, ls_source TYPE abap_trans_resbind, lv_xmlstr TYPE xstring, .....
Then the table must be filled with content to export:
* add table 1 GET REFERENCE OF lt_my_table1 INTO ls_source-value. ls_source-name = 'my_table1'. APPEND ls_source TO lt_source. * add structure 1 GET REFERENCE OF lt_my_structure1 INTO ls_source-value. ls_source-name = 'my_structure1'. APPEND ls_source TO lt_source. * add table 2 GET REFERENCE OF lt_my_table1 INTO ls_source-value. ls_source-name = 'my_table2'. APPEND ls_source TO lt_source.
You can see, that this is a mixture of tables and structures and tables, again.
Step 2: then we have to use the transformation
Create the call of the transformation, handled by a try-catch-structure.
TRY. CALL TRANSFORMATION zmy_complex_transformation SOURCE (lt_source) RESULT XML lv_xmlstr. CATCH cx_root. "error handling ... ENDTRY. "then follows implementation to store this lv_xmlstr to a file XML file
Step 3: after this we can develop the XSLT transformation programm ‘zmy_complex_transformation’
This is just a simple frame, if you create a new XSLT program
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output encoding="iso-8859-1" indent="yes" method="xml" version="1.0"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <!-- ************* here is my specific code *************** --> </xsl:template> </xsl:transform>
Step 4: ready ?
No … this was just the framework to export ABAP data via XSLT to XML. While development of XSTL program you will have a lot of exceptions type of CX_XSLT_ … even in the following code processing.
No we have to talk about how to get the ABAP exact output of XML ! The situation is shown in the diagram of the SAP help very well. In our case we want to do a red marked serialization from ABAP via asXML (by using a XSTL) to XML.
This was unclear to me a long time. I did not realize, that there is a real transformation already given named “ID”, delivered by SAP to do this.
So lets have a look to this delivered transformation:
XSLT experts will have some fun on this, because, the code is rather easy and will pass everything without any mapping. But if you are not very familiar, you will have thousands questions first 😉
So this was the secret and the solution for my problem 😎 …
To get an output I modified the code of step 2 like this:
DATA: lv_debug TYPE flag, lo_doc TYPE REF TO cl_xml_document, lv_subrc TYPE sy-subrc. ... IF lv_debug IS NOT INITIAL. "<<<<<< change manually to X while debugging CALL TRANSFORMATION id "SAP standard transformation ... let's pass everything without any mapping SOURCE (lt_source) RESULT XML lv_xmlstr. CLEAR lo_doc. CREATE OBJECT lo_doc. * load hex string to XML document ... CALL METHOD lo_doc->parse_xstring EXPORTING stream = lv_xmlstr RECEIVING retcode = lv_subrc. * ... and do an output to the local filesystem CALL METHOD lo_doc->export_to_file EXPORTING filename = 'c:\temp\input.xml' RECEIVING retcode = lv_subrc. ELSE. CALL TRANSFORMATION zca_tr_export_list SOURCE (lt_source) RESULT XML lv_xmlstr. ENDIF.
Now we have the possibility to create an XML with the direct APAB output to get an better imagination of the data structures. After running this code we will have an XML file on the specified path. I called this file input file, because it’s the input of our transformation.
Then we can go to the XSLT debugger by using this XML file for the XSLT transformation:
Within the debugger you can exactly step trough the XSLT code and see what’s going wrong with it … or hopefully not.
That’s all and happy debugging 😆
I hope you had some fun and can use these information.
Ahhh … I forgot one interesting code gift.
One additional note:
You can also implement a nice little XML viewer in your code to get the result … if you get or need one. So use this code to get a preview:
IF lv_xmlstr IS NOT INITIAL. CALL FUNCTION 'DISPLAY_XML_STRING' EXPORTING xml_string = lv_xmlstr * TITLE = * STARTING_X = 5 * STARTING_Y = 5 EXCEPTIONS no_xml_document = 1 OTHERS = 2. ENDIF.
The XML viewer looks like this short example: