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

Call transformation for xml

Former Member
0 Likes
8,065

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

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
5,787

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

21 REPLIES 21
Read only

Sandra_Rossi
Active Contributor
5,788

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

Read only

0 Likes
5,787

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.

Read only

0 Likes
5,787

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)

Read only

0 Likes
5,787

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?

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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?

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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.

Read only

0 Likes
5,787

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?

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

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

Read only

0 Likes
5,787

i didnt understnad what regex is all about and why its used

Read only

0 Likes
5,787

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