You are on page 1of 11

SAP TECHED ’04

ABAP – XML MAPPING


ABAP 252

Exercises / Solutions

KARSTEN BOHLMANN, SAP AG


CHRISTOPH WEDLER, SAP AG
PETER MCNULTY, SAP LABS
SAP TECHED ’04 1

ABAP – XML MAPPING

The context for the exercises in this unit is based on the "customers" example. This customers list contains three parts: unique id,
name, and address.

We will assume that there is some XML standard for customers and our task is to map data in an XML document to an ABAP table of
a data type (provided by an application) and back. We first perform this task using XSLT, later we use Simple Transformations.

Exercise 1: Calling Transformations from ABAP


In this exercise, you will use the ABAP statement CALL TRANSFORMATION to call XSLT and ST transformations from ABAP; these
will be transformations from ABAP to XML and back.
a) Copy report ZABAP252_00 to ZABAP252_nn where nn (two digits) is your group number. When copying, mark the
checkboxes "User interface" and "Screens" (the checkboxes"Source" and "Text elements" are already marked)! Save the
report (and the transformations copied in the following exercises) as local objects.
b) Change the VALUE of the constant group_nr (at the beginning of the report) to nn where nn (two digits) is your group
number.
c) In form exercise, (line 92ff), insert twice the ABAP statement CALL TRANSFORMATION to call the transformation trans
where trans is the value of variable trans_name (i.e., you use the dynamic call): first for the ABAP to XML
transformation and second for the XML to ABAP transformation. The ABAP data is (to be) stored in variable customers,
the XML document is (to be) stored in variable xml, the data root for the transformation is called CUSTOMER_TABLE.
Execute the report with option "Exercise 1". Select "ABAP to XML transformation" to check the first CALL TRANSFORMATION
statement (you see the XML result in an HTML viewer), select "XML to ABAP transformation" to check the second (you see the
ABAP result in an ABAP list).

General Remarks
In order to write transformations between two formats, it is important to fully understand both the formats and how the mapping
should work. After executing the report in Exercise 1, you have a general idea of how the ABAP data type and the "standard" XML
format for customers look like. Here is some additional information:
a) The ABAP data type (t_customers) for customers is defined at the beginning of program ZABAP252_nn (line 24ff), it is a
table of structures (with substructures).
b) The "standard" XML format for customers has a root named Customers in the namespace
http://www.standards.org/customers. It has 0 or more subelements named Customer each of which corresponds to
a table line in the ABAP table. The attribute id and the subelements Name and Address correspond to the similar named
components of the table line. These two subelements have the following properties:
• The element Name has two subelements Last and First if there is no middle name. It has the subelements Last and
Given otherwise where Given has two subelements First and Middle.
• The subelements of Address are all optional and can appear in any order. A missing subelement State corresponds to
the ABAP component STATE to have the value 'XX', other missing subelements correspond to initial values of the
similar named components.
c) For the curious: The customer XML document (used in the report for the XML to ABAP transformations) comes from an
XSLT transformation (ZABAP252_CUSTOMERS) with literal content, the output of the transformation does not depend on
the input. The customer ABAP table (used in the report for the ABAP to XML transformations) comes from transforming the
customer XML document with the proposed solution of Exercise 4.

Exercise 2: Using XSLT for ABAP-XML Mappings


ABAP -XML mappings can be defined using the XSLT programming language. Using XSLT requires you to write two programs: one
for the ABAP to XML transformation and one for the XML to ABAP transformation. You find some information about XSLT
instructions and XPath expressions at
SAP TECHED ’04 OCTOBER 2004 2

http://evphl401.phl.sap.corp:50180/sap/bc/bsp/sap/zabap252/intro.htm

a) Copy the XSLT transformations ZABAP252_A2X_00 to ZABAP252_A2X_nn and ZABAP252_X2A_00 to


ZABAP252_X2A_nn where nn (two digits) is your group number. You might want to use transaction SE80, toolbar "Other
Object…", tab "More…", selection "Transformation" to copy the transformation.
b) Write the ABAP to XML transformation. Your program ZABAP252_A2X_nn already has a (incomplete) template which
matches the root CUSTOMER_TABLE in the asXML format and produces the (still empty) top element of the customer
XML document.
c) Write the XML to ABAP transformation. Your program ZABAP252_X2A_nn already has a (incomplete) template which
matches the top element of customer XML documents and produces the asXML envelope and the (still empty) root
element CUSTOMER_TABLE.
Execute the report with option "Exercise 2". Select "ABAP to XML transformation" to check the transformation
ZABAP252_A2X_nn, select "XML to ABAP transformation" to check the transformation ZABAP252_X2A_nn.

Exercise 3: Using ST for ABAP-XML Mappings, simplified version


Simple Transformations are specialized for ABAP-XML mappings; one ST program can be used for the ABAP to XML
transformation and back. For simple mappings, ST programs look like a schema for the XML document, inriched with references to
corresponding ABAP data structures.
a) Copy the ST program ZABAP252_ST3_00 to ZABAP252_ST3_nn where nn (two digits) is your group number.
b) Write the ST program which produces a simplified version of the XML document, just containing the id and the last name.
Your program ZABAP252_A2X_nn already has a (incomplete) template which references the root CUSTOMER_TABLE
and produces the top element of the customer XML document.
c) Allow your ST program to work on the full version of an customer XML document (doing an XML to ABAP mapping) by
allowing the ST engine to skip elements you do not handle in this exercise (subelements First, Given and Address). The
ST instruction <tt:skip count="*"/> skips any number of elements during the deserialization.
Execute the report with option "Exercise 3". Select both "ABAP to XML transformation" and "XML to ABAP transformation" to
check the transformation ZABAP252_ST3_nn.

Exercise 4: Using ST for ABAP-XML Mappings, full version


Simple Transformations can use conditionals to produce and parse irregular XML documents. You will use them in this exercise.
a) Copy the ST program ZABAP252_ST4_00 to ZABAP252_ST4_nn where nn (two digits) is your group number.
Alternatively, copy ZABAP252_ST3_nn to ZABAP252_ST4_nn and delete the <tt:skip> instructions.
b) Extend the ST program to produce the full version of the XML document. For the deserialization, please consider that the
component STATE should be set to 'XX' if there is no element State in the XML document.
Execute the report with option "Exercise 4". Select both "ABAP to XML transformation" and "XML to ABAP transformation" to
check the transformation ZABAP252_ST4_nn.

Exercise 5 (optional): Using ST for ABAP-XML Mappings, full version, modular


A specific ABAP data type is often used in the definition of other data types. Consequently, the XML mapping of this data might be
used in the XML mappings of other data types. The ST constructs for modularization allow you to define this XML mapping at one
place and use it in the XML mappings of the other data types.
a) Copy ZABAP252_ST4_nn to ZABAP252_ST5_nn and create a new ST program called ZABAP252_ST5_ADDR_nn.
b) Define a new template for the mapping between component NAME and the element Name. In the main template, apply the
new template instead doing the name mapping in-place.
c) Define the main template of ZABAP252_ST5_ADDR_nn to do the mapping between component ADDR and the element
Address. In the main template of program ZABAP252_ST5_nn, call the new template instead doing the address mapping
in-place.
Execute the report with option "Exercise 5". Select both "ABAP to XML transformation" and "XML to ABAP transformation" to
check the transformations ZABAP252_ST5_nn and ZABAP252_ST5_ADDR_nn.
SAP TECHED ’04 OCTOBER 2004 3

Proposed Solution for Exercise 1

*&---------------------------------------------------------------------*
*& Report ZABAP252_99
*&
*&---------------------------------------------------------------------*
*& Exercises for TechEd 04: workshop ABAP 252
*& XSLT and ST
*&---------------------------------------------------------------------*

REPORT zabap252_99.
CONSTANTS: group_nr TYPE n LENGTH 2 VALUE '99'.

PARAMETERS:
exerc1 TYPE char1 RADIOBUTTON GROUP exer DEFAULT 'X',
exerc2 TYPE char1 RADIOBUTTON GROUP exer,
exerc3 TYPE char1 RADIOBUTTON GROUP exer,
exerc4 TYPE char1 RADIOBUTTON GROUP exer,
exerc5 TYPE char1 RADIOBUTTON GROUP exer.
SELECTION-SCREEN SKIP 1.
PARAMETERS:
abap2xml TYPE char1 RADIOBUTTON GROUP dirn DEFAULT 'X',
xml2abap TYPE char1 RADIOBUTTON GROUP dirn.

* The ABAP data type (usually in Dictionary)


TYPES: BEGIN OF t_name,
last TYPE string,
first TYPE string,
mid TYPE string,
END OF t_name.
TYPES: BEGIN OF t_addr,
city TYPE string,
zip_code TYPE n LENGTH 5,
state TYPE c LENGTH 2,
street TYPE string,
street_no TYPE i,
END OF t_addr.
TYPES: BEGIN OF t_customer,
id TYPE n LENGTH 4,
name TYPE t_name,
addr TYPE t_addr,
END OF t_customer.
TYPES t_customers TYPE STANDARD TABLE OF t_customer.

*---------------------------------------------------------------------*
*
* Main Program
*
*---------------------------------------------------------------------*

START-OF-SELECTION.
DATA ex TYPE REF TO cx_root.
DATA ex_st TYPE REF TO cx_st_error.
DATA ex_xslt TYPE REF TO cx_xslt_system_error.
DATA prog_name TYPE string.
DATA line TYPE i.

TRY.
CASE 'X'.
WHEN exerc1.
SAP TECHED ’04 OCTOBER 2004 4

PERFORM exercise USING 'ST4' 'ST4' '99'.


WHEN exerc2.
PERFORM exercise USING 'A2X' 'X2A' group_nr.
WHEN exerc3.
PERFORM exercise USING 'ST3' 'ST3' group_nr.
WHEN exerc4.
PERFORM exercise USING 'ST4' 'ST4' group_nr.
WHEN exerc5.
PERFORM exercise USING 'ST5' 'ST5' group_nr.
ENDCASE.
CATCH cx_st_error INTO ex_st.
ex_st->get_st_source_position( IMPORTING
prog_name = prog_name
line = line ).
BREAK-POINT.
CATCH cx_xslt_system_error INTO ex_xslt.
ex_xslt->get_xslt_source_position( IMPORTING
prog_name = prog_name
prog_line = line ).
BREAK-POINT.
CATCH cx_transformation_error INTO ex.
BREAK-POINT.
ENDTRY.

*&--------------------------------------------------------------------*
*& Form exercise
*&--------------------------------------------------------------------*
* Run exercise, both for ABAP to XML and v/v
*---------------------------------------------------------------------*
* -->A2X Part of name for ABAP to XML transformation
* -->X2A ditto, for XML to ABAP, with ST: same as A2X
* -->GN group number, usually constant GROUP_NR
*---------------------------------------------------------------------*
FORM exercise USING a2x TYPE string x2a TYPE string gn TYPE n
RAISING cx_transformation_error.
DATA trans_name TYPE string.
DATA customers TYPE t_customers.
DATA xml TYPE xstring.

IF xml2abap IS INITIAL.
CONCATENATE 'ZABAP252_' a2x '_' gn INTO trans_name.
PERFORM load_abap CHANGING customers.
* >>> ABAP to XML transformation in trans_name (root CUSTOMER_TABLE)
CALL TRANSFORMATION (trans_name)
SOURCE customer_table = customers
RESULT XML xml.
PERFORM show_xml USING xml.
ELSE.
CONCATENATE 'ZABAP252_' x2a '_' gn INTO trans_name.
PERFORM load_xml CHANGING xml.
* >>> XML to ABAP transformation in trans_name (root CUSTOMER_TABLE)
CALL TRANSFORMATION (trans_name)
SOURCE XML xml
RESULT customer_table = customers.
PERFORM show_abap USING customers.
ENDIF.
ENDFORM. "exercise

*=====================================================================*
SAP TECHED ’04 OCTOBER 2004 5

*
* Load/Show ABAP/XML (general procedures)
*
*=====================================================================*

TYPES: m_xmlln TYPE x LENGTH 72,


m_xml TYPE STANDARD TABLE OF m_xmlln.

DATA m_xml TYPE m_xml.


DATA html_viewer TYPE REF TO cl_gui_html_viewer.
DATA gen_url TYPE c LENGTH 500.

*&--------------------------------------------------------------------*
*& Form load_abap
*&--------------------------------------------------------------------*
* load ABAP data (from XML data in XSLT prg ZABAP252_CUSTOMERS)
*---------------------------------------------------------------------*
* -->CUSTOMERS ABAP customer table
*---------------------------------------------------------------------*
FORM load_abap CHANGING customers TYPE t_customers.
DATA xml TYPE xstring.
PERFORM load_xml CHANGING xml.
CALL TRANSFORMATION zabap252_st4_99
SOURCE XML xml RESULT customer_table = customers.
ENDFORM. "load_abap

*&--------------------------------------------------------------------*
*& Form show_abap
*&--------------------------------------------------------------------*
* show ABAP data in an ABAP list
*---------------------------------------------------------------------*
* -->CUSTOMERS ABAP customer table
*---------------------------------------------------------------------*
FORM show_abap USING customers TYPE t_customers.
FIELD-SYMBOLS: <cust> TYPE t_customer.
FORMAT COLOR COL_HEADING.
WRITE: 'ID',
AT 6 'NAME-{FIRST,MID,LAST}',
AT 40 'ADDR-{ZIP_CODE,CITY,STATE}',
AT /40 'ADDR-{STREET_NO,STREET}'.
FORMAT COLOR COL_BACKGROUND.
* SKIP.

LOOP AT customers ASSIGNING <cust>.


WRITE: / <cust>-id,
AT 6 <cust>-name-first, <cust>-name-mid, <cust>-name-last,
AT 40 <cust>-addr-zip_code, <cust>-addr-city, <cust>-addr-state,
AT /40(*) <cust>-addr-street_no, <cust>-addr-street.
ENDLOOP.
ENDFORM. "show_abap

*&--------------------------------------------------------------------*
*& Form load_xml
*&--------------------------------------------------------------------*
* load XML data (from XML data in XSLT prg ZABAP252_CUSTOMERS)
*---------------------------------------------------------------------*
* -->XML XML as XSTRING
*---------------------------------------------------------------------*
SAP TECHED ’04 OCTOBER 2004 6

FORM load_xml CHANGING xml TYPE xstring.


DATA dummy TYPE i.
CALL TRANSFORMATION zabap252_customers
SOURCE dummy = dummy
RESULT XML xml.
ENDFORM. "load_xml

*&--------------------------------------------------------------------*
*& Form show_xml
*&--------------------------------------------------------------------*
* show XML in HTML Viewer
*---------------------------------------------------------------------*
* -->XML XML to show as XSTRING, exception if no XML
*---------------------------------------------------------------------*
FORM show_xml USING xml TYPE xstring RAISING cx_xslt_runtime_error.
" Misuse of CALL TRANSFORMATION to convert xstring to table of X...:
CALL TRANSFORMATION id SOURCE XML xml RESULT XML m_xml.
CALL SCREEN 0100.
ENDFORM. "show_xml

*---------------------------------------------------------------------*
* MODULE status_0100 OUTPUT
*---------------------------------------------------------------------*
* helper module to use HTML Viewer, uses PF-Status HTML_VIEWER
*---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'HTML_VIEWER'.
CREATE OBJECT html_viewer
EXPORTING parent = cl_gui_container=>screen0.

CALL METHOD html_viewer->load_data


IMPORTING
assigned_url = gen_url
CHANGING
data_table = m_xml
EXCEPTIONS
OTHERS = 1.

IF sy-subrc <> 0 OR gen_url IS INITIAL.


MESSAGE e008(cnht). " error in init of HTML control
ENDIF.
CALL METHOD html_viewer->show_url
EXPORTING
url = gen_url.
ENDMODULE. "status_0100 OUTPUT

*---------------------------------------------------------------------*
* MODULE user_command_0100 INPUT
*---------------------------------------------------------------------*
* helper module for navigation in HTML Viewer
*---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
SET SCREEN 0.
IF html_viewer IS NOT INITIAL.
CALL METHOD html_viewer->free( ).
CLEAR html_viewer.
ENDIF.
ENDMODULE. "user_command_0100 INPUT
SAP TECHED ’04 OCTOBER 2004 7

Proposed Solution for Exercise 2, ABAP to XML

<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:asx="http://www.sap.com/abapxml"
exclude-result-prefixes="asx" >

<xsl:strip-space elements="*"/>
<xsl:output encoding="utf-8" indent="no" omit-xml-declaration="yes"/>

<xsl:template match="/asx:abap/asx:values/CUSTOMER_TABLE">

<c:Customers xmlns:c="http://www.standards.org/customers" version="2.0">


<xsl:for-each select="*">
<Customer id="{ID}">

<xsl:for-each select="NAME[1]">
<Name>
<Last><xsl:value-of select="LAST"/></Last>
<xsl:choose>
<xsl:when test="MID">
<Given>
<First><xsl:value-of select="FIRST"/></First>
<Middle><xsl:value-of select="MID"/></Middle>
</Given>
</xsl:when>
<xsl:otherwise>
<First><xsl:value-of select="FIRST"/></First>
</xsl:otherwise>
</xsl:choose>
</Name>
</xsl:for-each>

<xsl:for-each select="ADDR[1]">
<xsl:variable name="s" select="string(STATE)"/>
<Address>
<City><xsl:value-of select="CITY"/></City>
<ZIP><xsl:value-of select="ZIP_CODE"/></ZIP>
<xsl:if test="$s!='XX'">
<State><xsl:value-of select="$s"/></State>
</xsl:if>
<Street>
<xsl:value-of select="STREET_NO"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="STREET"/>
</Street>
</Address>
</xsl:for-each>

</Customer>
</xsl:for-each>
</c:Customers>

</xsl:template>
</xsl:transform>
SAP TECHED ’04 OCTOBER 2004 8

Proposed Solution for Exercise 2, XML to ABAP

<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:asx="http://www.sap.com/abapxml"
exclude-result-prefixes="c" >

<xsl:strip-space elements="*"/>
<xsl:output encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="/c:Customers">

<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">


<asx:values>
<CUSTOMER_TABLE>
<xsl:for-each select="Customer">

<item>
<ID><xsl:value-of select="@id"/></ID>

<xsl:for-each select="Name[1]">
<NAME>
<LAST><xsl:value-of select="Last"/></LAST>
<xsl:choose>
<xsl:when test="Given">
<FIRST><xsl:value-of select="Given[1]/First"/></FIRST>
<MID><xsl:value-of select="Given[1]/Middle"/></MID>
</xsl:when>
<xsl:otherwise>
<FIRST><xsl:value-of select="First"/></FIRST>
</xsl:otherwise>
</xsl:choose>
</NAME>
</xsl:for-each>

<xsl:for-each select="Address[1]">
<xsl:variable name="s" select="string(Street)"/>
<xsl:variable name="p" select="sap:find-first($s,', ')"/>
<ADDR>
<CITY><xsl:value-of select="City"/></CITY>
<ZIP_CODE><xsl:value-of select="ZIP"/></ZIP_CODE>
<STATE><xsl:value-of select="sap:if(State, State, 'XX')"/></STATE>
<STREET><xsl:value-of select="substring($s,$p +2)"/></STREET>
<STREET_NO><xsl:value-of select="substring($s,1,$p -1)"/></STREET_NO>
</ADDR>
</xsl:for-each>

</item>
</xsl:for-each>
</CUSTOMER_TABLE>
</asx:values>
</asx:abap>

</xsl:template>
</xsl:transform>
SAP TECHED ’04 OCTOBER 2004 9

Proposed Solution for Exercise 4

<?sap.transform simple?>
<tt:transform
xmlns:tt="http://www.sap.com/transformation-templates"
xmlns:c="http://www.standards.org/customers" >

<tt:root name="CUSTOMER_TABLE"/>
<tt:template>

<c:Customers version="2.0" tt:ref="CUSTOMER_TABLE">


<tt:loop name="C">
<Customer>
<tt:attribute name="id" value-ref="ID"/>
<Name>
<Last tt:value-ref="NAME.LAST"/>
<tt:switch>
<tt:cond data="initial(NAME.MID)">
<First tt:value-ref="NAME.FIRST"/>
</tt:cond>
<tt:cond>
<Given>
<First tt:value-ref="NAME.FIRST"/>
<Middle tt:value-ref="NAME.MID"/>
</Given>
</tt:cond>
</tt:switch>
</Name>

<!-- default for STATE, when deserializing -->


<tt:assign to-ref="ADDR.STATE" val="'XX'"/>
<Address tt:ref="ADDR">
<!-- address elements are in any order -->
<tt:group>
<tt:cond>
<City tt:value-ref="CITY"/>
</tt:cond>
<tt:cond>
<Street>
<!-- values are separated by ", " -->
<tt:value ref="STREET_NO"/>
<tt:text>, </tt:text>
<tt:value ref="STREET"/>
</Street>
</tt:cond>
<!-- STATE is an optional element -->
<tt:cond s-check="STATE != 'XX'">
<State tt:value-ref="STATE"/>
</tt:cond>
<tt:cond>
<ZIP tt:value-ref="ZIP_CODE"/>
</tt:cond>
</tt:group>
</Address>

</Customer>
</tt:loop>
</c:Customers>
</tt:template>
</tt:transform>
SAP TECHED ’04 OCTOBER 2004 10

Copyright 2004 SAP AG. All Rights Reserved

„ No part of this publication may be reproduced or transmitted in any form or for any purpose without the
express permission of SAP AG. The information contained herein may be changed without prior notice.
„ Some software products marketed by SAP AG and its distributors contain proprietary software components
of other software vendors.
„ Microsoft, Windows, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation.
„ IBM, DB2, DB2 Universal Database, OS/2, Parallel Sysplex, MVS/ESA, AIX, S/390, AS/400, OS/390,
OS/400, iSeries, pSeries, xSeries, zSeries, z/OS, AFP, Intelligent Miner, WebSphere, Netfinity, Tivoli, and
Informix are trademarks or registered trademarks of IBM Corporation in the United States and/or other
countries.
„ Oracle is a registered trademark of Oracle Corporation.
„ UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group.
„ Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or
registered trademarks of Citrix Systems, Inc.
„ HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®, World Wide Web
Consortium, Massachusetts Institute of Technology.
„ Java is a registered trademark of Sun Microsystems, Inc.
„ JavaScript is a registered trademark of Sun Microsystems, Inc., used under license for technology invented
and implemented by Netscape.
„ MaxDB is a trademark of MySQL AB, Sweden.
„ SAP, R/3, mySAP, mySAP.com, xApps, xApp, SAP NetWeaver and other SAP products and services
mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in
Germany and in several other countries all over the world. All other product and service names mentioned
are the trademarks of their respective companies. Data contained in this document serves informational
purposes only. National product specifications may vary.
„ These materials are subject to change without notice. These materials are provided by SAP AG and
its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty
of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The
only warranties for SAP Group products and services are those that are set forth in the express warranty
statements accompanying such products and services, if any. Nothing herein should be construed as
constituting an additional warranty.

SAP assumes no responsibility for errors or omissions in these materials.

You might also like