2011 Jul 23 12:56 AM
Hi Friends,
I am trying to generate xml as below - the final result should be like below.
<DETAILS>
<PURCHASE_ORDER>
<ROW>
<ORDER_NUMBER> 12345 </ORDER_NUMBER>
<SOLDTO_ID>61660482</SOLDTO_ID>
</ROW>
</PURCHASE_ORDER>
</DETAILS>
I AM USING below code for the same ( zvorder is a structure with fields order_number, soldto_id
TYPES : BEGIN OF store,
purchase_order TYPE zvorder,
END OF store.
DATA: BEGIN OF header,
details TYPE store,
END OF header.
DATA : w_xml TYPE string.
header-details-purchase_order-order_number = '12345'.
header-details-purchase_order-soldto_id = '61660482'.
CALL TRANSFORMATION id
SOURCE row = header
RESULT XML w_xml
OPTIONS xml_header = 'no'.
With above code I am not getting what I wanted ( as above xml ). I am getting the result like below...
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"><asx:values>**
<ROW>
<DETAILS>
<PURCHASE_ORDER>
<ORDER_NUMBER>12345</ORDER_NUMBER>
<SOLDTO_ID> 61660482 </SOLDTO_ID>
</PURCHASE_ORDER>
</DETAILS>
</ROW>
</asx:values></asx:abap>
Question is 1. How to remove the <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"><asx:values> and </asx:values></asx:abap> at the start and end?
2. How to bring the <ROW> after <PURCHASE_ORDER> and </ROW> before </PURCHASE_ORDER>.
Kindly help, as I am new to this xml generation.
thanks in advance.
Niraja
2011 Jul 23 11:10 PM
Hi Niraja,
The ID transformation is an XSLT only used for storing/reading data objects into/from asXML (with the asx namespace you see).
Usually, we create a custom Z transformation (transaction STRANS). You have the choice between 2 languages: ST and XSLT. First one must be chosen by default, and especially if you need high performance, second one for complex transformations.
In your case, it will look like this:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ss="cc">
<tt:root name="ABAP_ROOT"/>
<tt:template>
<DETAILS>
<PURCHASE_ORDER>
<ROW>
<tt:copy ref=".ABAP_ROOT.DETAILS.PURCHASE_ORDER"/>
</ROW>
</PURCHASE_ORDER>
</DETAILS>
</tt:template>
</tt:transform>
It will be called like this:
types :begin of zvorder,
order_number type char10,
soldto_id TYPE char10,
end of zvorder.
TYPES : BEGIN OF store,
purchase_order TYPE zvorder,
END OF store.
DATA: BEGIN OF header,
details TYPE store,
END OF header.
DATA : w_xml TYPE string.
header-details-purchase_order-order_number = '12345'.
header-details-purchase_order-soldto_id = '61660482'.
CALL TRANSFORMATION zzysro_st
SOURCE abap_root = header
RESULT XML w_xml.
BR
Sandra
Hi Friends,
I am trying to generate xml as below - the final result should be like below.
<DETAILS>
<PURCHASE_ORDER>
<ROW>
<ORDER_NUMBER> 12345 </ORDER_NUMBER>
<SOLDTO_ID>61660482</SOLDTO_ID>
</ROW>
</PURCHASE_ORDER>
</DETAILS>
I AM USING below code for the same ( zvorder is a structure with fields order_number, soldto_id
TYPES : BEGIN OF store,
purchase_order TYPE zvorder,
END OF store.
DATA: BEGIN OF header,
details TYPE store,
END OF header.
DATA : w_xml TYPE string.
header-details-purchase_order-order_number = '12345'.
header-details-purchase_order-soldto_id = '61660482'.
CALL TRANSFORMATION id
SOURCE row = header
RESULT XML w_xml
OPTIONS xml_header = 'no'.
With above code I am not getting what I wanted ( as above xml ). I am getting the result like below...
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"><asx:values>**
<ROW>
<DETAILS>
<PURCHASE_ORDER>
<ORDER_NUMBER>12345</ORDER_NUMBER>
<SOLDTO_ID> 61660482 </SOLDTO_ID>
</PURCHASE_ORDER>
</DETAILS>
</ROW>
</asx:values></asx:abap>
Question is 1. How to remove the <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0"><asx:values> and </asx:values></asx:abap> at the start and end?
2. How to bring the <ROW> after <PURCHASE_ORDER> and </ROW> before </PURCHASE_ORDER>.
Kindly help, as I am new to this xml generation.
thanks in advance.
Niraja
2011 Jul 23 11:10 PM
Hi Niraja,
The ID transformation is an XSLT only used for storing/reading data objects into/from asXML (with the asx namespace you see).
Usually, we create a custom Z transformation (transaction STRANS). You have the choice between 2 languages: ST and XSLT. First one must be chosen by default, and especially if you need high performance, second one for complex transformations.
In your case, it will look like this:
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ss="cc">
<tt:root name="ABAP_ROOT"/>
<tt:template>
<DETAILS>
<PURCHASE_ORDER>
<ROW>
<tt:copy ref=".ABAP_ROOT.DETAILS.PURCHASE_ORDER"/>
</ROW>
</PURCHASE_ORDER>
</DETAILS>
</tt:template>
</tt:transform>
It will be called like this:
types :begin of zvorder,
order_number type char10,
soldto_id TYPE char10,
end of zvorder.
TYPES : BEGIN OF store,
purchase_order TYPE zvorder,
END OF store.
DATA: BEGIN OF header,
details TYPE store,
END OF header.
DATA : w_xml TYPE string.
header-details-purchase_order-order_number = '12345'.
header-details-purchase_order-soldto_id = '61660482'.
CALL TRANSFORMATION zzysro_st
SOURCE abap_root = header
RESULT XML w_xml.
BR
Sandra
2011 Jul 24 12:05 AM
Hi Sandra,
So in my scenario how can i get the output ?
<DETAILS>
<PURCHASE_ORDER>
<ROW>
<ORDER_NUMBER> 12345 </ORDER_NUMBER>
<SOLDTO_ID>61660482</SOLDTO_ID>
</ROW>
</PURCHASE_ORDER>
</DETAILS>
Isnt this possible then? could you please let me know the solution.
2011 Jul 24 9:36 AM
Hi Niraja,
as explained in my post above. What is the issue with it? Do you want to get rid of the XML header? Then add the keyword you used initialy in CALL TRANSFORMATION.
Or tell me if you need more information.
Sandra
Edit: note that I named the new ST transformation ZZYSRO_ST (as you can see in the CALL TRANSFORMATION)
2011 Jul 25 7:21 AM
hi sandra,
sorry but i didnt understand what u said. i am new to this xml transformation, even though i used the option no header but still the header is coming..
I didnt understand what u said about STRANs ..
could you tell me in detail how to achieve this?
2011 Jul 25 9:27 AM
Hi Niraja,
When you use CALL TRANSFORMATION, from a data object to an XML string, it first converts the data object in an XML called asXML which is proprietary SAP (you'll find information in SAP library also under title "canonical XML representation of ABAP data"), and then calls a "transformation" workbench object, which is defined using STRANS transaction, which transforms an XML into another XML. This transformation object may be written in one of 2 languages: either XSLT which is a "well-known" worldwide open standard, or ST which is proprietary SAP (simpler and much faster).
When you use CALL TRANSFORMATION ID, ID is a transformation object, which in fact does nothing (so it returns the asXML when you transform from a data object to XML).
Here was the background.
So you have to go to the STRANS transaction, create the transformation object and then call it from your ABAP, as explained in my first answer. Try first, and revert back to SDN if you have any more question.
Note that you may find the documentation for transformations in the SAP library (as usually). There are also a few very interesting articles in SDN.
BR
Sandra
2011 Jul 25 7:36 PM
HI Sandra,
I have done this simple one but I am getting error .
My test program has below code:
TYPES: BEGIN OF ty_test1,
col1(10) TYPE c,
col2(10) TYPE c,
END OF ty_test1.
DATA: PARA TYPE ty_test1.
DATA: result TYPE ty_test1.
DATA: xml_string TYPE string.
PARA-COL1 = 'Name'.
PARA-COL2 = 'Last'.
CALL TRANSFORMATION ztest
SOURCE row = PARA
RESULT XML xml_string.
in STRANS I created simple transformation : ZTEST.
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="PARA"/>
<tt:template>
<X tt:ref="PARA">
<X1>
<tt:value ref="PARA.COL1" />
</X1>
</X>
</tt:template>
</tt:transform>
But I am getting short dump as error shows :
"Error when accessing variables during execution of ST program. "
The reason for the exception is: The goal was to access variable "PARA.COL1". However, this access was not possible. "
I dont know what the error is, but I am not able to move over from here and solve this error. Could you please let me know..
I just followed the example given on simple transformations, by clicking F1 on CALL Transformation abap statement..
please reply
2011 Jul 25 8:18 PM
I am able to get the correct output now.
mistake was
i have to give PARA = PARA
in
CALL TRANSFORMATION ztest
SOURCE row = PARA
I am checking how to make this for internal table..
Niraja
2011 Jul 25 8:20 PM
I am able to get the correct output now.
mistake was
i have to give PARA = PARA
in
CALL TRANSFORMATION ztest
SOURCE row = PARA
I am checking how to make this for internal table..
Niraja
2011 Jul 25 9:11 PM
Hi Niraja,
did you at least try the program + transformation I gave you, does it work for you? (it works for me, so...)
Do you want to achieve something special now (may I help?), or do you experience by yourself?
BR
Sandra
2011 Jul 25 9:16 PM
Yes Sandra,
Simple output I am able to transform. Now I am trying to see how to convert the data from internal table.
Like for ex: Sales order, for header details I use structure and convert into xml.
but say I have internal table with all the items details... all the items of that sales order.
how to write the code in program's call transformation ?
what to write in strans transformation ?
if you can let me know would be great help.
thanks
Niraja
2011 Jul 26 11:04 AM
Hi Niraja,
Here is the code with the loop. I prefer to show you a working example, instead of explaining, I think it's better to understand. You'll have to use <tt:loop>...</tt:loop> Note that the SAP library contains a few examples for most of ST elements.
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ss="cc">
<tt:root name="ABAP_ROOT"/>
<tt:template>
<DETAILS>
<PURCHASE_ORDER>
<tt:loop ref=".ABAP_ROOT.DETAILS.PURCHASE_ORDER" name="line"/> <!-- <===NEW -->
<ROW>
<tt:copy ref="$line"/><!-- <===CHANGED -->
</ROW>
</tt:loop>
</PURCHASE_ORDER>
</DETAILS>
</tt:template>
</tt:transform>
It will be called like this:
types :begin of zvorder,
order_number type char10,
soldto_id TYPE char10,
end of zvorder.
TYPES : BEGIN OF store,
purchase_order TYPE TABLE OF zvorder WITH DEFAULT KEY,"<===STRUCT -> ITAB
END OF store.
DATA order TYPE zvorder. "<=== NEW
DATA: BEGIN OF header,
details TYPE store,
END OF header.
DATA : w_xml TYPE string.
* ===>START OF CHANGED BLOCK
order-order_number = '12345'.
order-soldto_id = '61660482'.
APPEND order TO header-details-purchase_order.
order-order_number = '6789'.
order-soldto_id = 'ABCDEF'.
APPEND order TO header-details-purchase_order.
* <===END OF CHANGED BLOCK
CALL TRANSFORMATION zzysro_st
SOURCE abap_root = header
RESULT XML w_xml.
BR
Sandra
2011 Jul 28 7:45 PM
HI Sandra,
I have a question on my previous simple transformation example..
I observed that when a field has a blank value the xml tag its generating is like <SOLDTO_ID/> and not <SOLDTO_ID></SOLDTO_ID>
Is it possible to bring the tag as <SOLDTO_ID></SOLDTO_ID> when soldot_id has blank value ?
could you please answer this.
thanks
2011 Jul 28 9:40 PM
Hi Niraja,
I'm not XSL/ST expert, so I will answer with my ABAP knowledge (maybe the solution would be easier with XSL, but that would require you to learn XSL now :-p). The easier, for me, would be to convert these empty elements using regular expressions after the transformation, something like:
data l_xml TYPE string.
l_xml = `<TEST1/><TEST2 attr='b'/>`.
REPLACE ALL OCCURRENCES OF REGEX '<([^><\s]+)( [^><]+)?/>' IN l_xml WITH '<$1$2></$1>'.
l_xml = `<TEST1></TEST1><TEST2 attr='b'></TEST2>`.
Though, my opinion is to stick to the empty element tag (<.../>) default behavior, I think it is more frequent than the use of "long empty form" (and relatively less memory-consuming).
BR
Sandra
2011 Jul 28 9:48 PM
I am not an expert too
so i m getting after transformation like this
<ORDERNUMBER>2343<ORDERNUMBER/>
</SOLDTO_ID>
So if I do REPLACE ALL OCCURRENCES OF REGEX '<([><\s]+)( [><]+)?/>' IN l_xml WITH '<$1$2></$1>'. will i get <SOLDTO_ID><SOLDTO_ID/> ??
what is REGEX ? and what did u gave in betwwen ' ' ?? i didnt understand '<$1$2></$1>' what you mean?
2011 Jul 28 10:03 PM
I was afraid you could ask me that 😛
Not that I don't know, but it's another domain.
Regex is short for Regular Expressions. You'll get more information in the ABAP documentation.
In short, I explain:
< if there's a <
\[...\] followed by character which can contain
^ neither ... nor ... nor
neither < nor > nor any space (\s)
+ what is before may be repeated (1 or more occurrences)
(...) what is inside is to be stored in variable $1
followed by
something that starts with a space (by the way, I should have used \s instead of the space to be perfectly correct), and followed by more or less the same thing
(...) what is inside is to be stored in variable $2
? what is before may be present or not (if not present, $2 will be empty)
and finished by />
then replace with what was found and rearrange a little bit
ALL OCCURRENCES OF is used to search other empty element tags
Sandra
2011 Jul 28 10:07 PM
try program DEMO_REGEX_TOY, you'll understand what happens with the regulation expression and replacement string above, as you can do some changes and see the results immediately.
2011 Jul 29 12:30 AM
In one ST how can i include both simple transformation and a loop ( internal table ).
like i have a structure with 3 fields..
<name>Myname<name/>
<street>mystreet<street/>
<city>mycity<city/>
<itemno>10<itemno/>
<product>testproduct1<product/>
<itemno>20<itemno/>
<product>testproduct2<product/>
In one ST how to achieve above?
2011 Jul 29 1:24 AM
I was able to do by using below tags
<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ss="cc">
<tt:root name="ABAP_ROOT"/>
<tt:template>
<ORDER_DETAILS>
<HEADER>
<ROW>
<tt:copy ref=".ABAP_ROOT.HEADER"/> * This has the complete structure of header , this is not internal table
</ROW>
</HEADER>
<ITEMDETAILS>
<ROW>
<tt:loop ref=".ABAP_ROOT.ORDER_DETAILS.ITEMDETAILS" name="line">
<tt:copy ref="$line"/>
</tt:loop>
</ROW>
</ITEMDETAILS>
</ORDER_DETAILS>
</tt:template>
</tt:transform>
this is working for me, where my transformation is
CALL TRANSFORMATION ztest
SOURCE abap_root = header
RESULT XML w_xml
OPTIONS xml_header = 'no'.
header has two field one with structure and another with internal table.
thanks Sandra
2011 Jul 29 2:51 PM
Hi Niraja,
it's more or less what I proposed to you (except I don't understand what you put ROW element outside the loop. So, that's fine if you're done with it.
Are you done with the regex too, or do you need more info?
Sandra
2011 Jul 29 11:22 PM
2011 Jul 30 8:32 PM
Hi Niraja,
After the CALL TRANSFORMATION has been processed, you can replace the empty element tags as you requested.
By the way, I forgot the ASSERT in the last statement of my regex code ( ASSERT l_xml = `<TEST1></TEST1><TEST2 attr='b'></TEST2>`.). ASSERT shows what situation the programmer is certain of, that helps reading the code, I often use it to say "that's what we get).
Here is the code that you add at the end of the ABAP code in your last post:
REPLACE ALL OCCURRENCES OF REGEX '<([^><\s]+)( [^><]+)?/>' IN w_xml WITH '<$1$2></$1>'.
What it does: Let's figure that after your CALL TRANSFORMATION, you get w_xml containing an empty element tag <SOLDTO_ID/>. The REPLACE above will replace it with <SOLDTO_ID></SOLDTO_ID>.
BR
Sandra
| User | Count |
|---|---|
| 4 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |