In the previous post, we discussed how easy it is to implement ABAP Mapping in SAP PI. This post aims to provide a complete code walkthrough using a small example.
We will use same example we used while doing XSLT mapping. This time we will use ABAP mapping. Lets say we have following XML as source message –
Our aim is to transform the above message into another message shown below such that first name and last name is concatenated into a single field.
ABAP Mapping Implementation
Create an ABAP objects class say ZCL_SIMPLE_ABAP_MAPPING as explained in the previous post. The class must implement the interface IF_MAPPING. The method EXECUTE of this interface will serve as our ABAP mapping logic. Implement the EXECUTE method in the class as described below.
We will use SAP’s iXML parser to parse the source XML. The code for the execute method is given below. The code is well commented for easy understanding.
METHOD if_mapping~execute.
* initialize iXML
TYPE-POOLS: ixml.
CLASS cl_ixml DEFINITION LOAD.
* create iXML factory object
DATA: ixmlfactory TYPE REF TO if_ixml.
ixmlfactory = cl_ixml=>create( ).
* create streamfactory object
DATA: streamfactory TYPE REF TO
if_ixml_stream_factory.
streamfactory = ixmlfactory->create_stream_factory( ).
* create input stream object
DATA: istream TYPE REF TO if_ixml_istream.
istream = streamfactory->create_istream_xstring( source ).
* initialize the input xml document
DATA: idocument TYPE REF TO if_ixml_document.
idocument = ixmlfactory->create_document( ).
* parse the input xml document
DATA: iparser TYPE REF TO if_ixml_parser.
iparser = ixmlfactory->create_parser(
stream_factory = streamfactory
istream = istream
document = idocument ).
iparser->parse( ).
* Getting the Message ID
* Not necessary. Just demonstrating how to access mapping parameters in ABAP mapping.
DATA: l_msgid_ref TYPE string.
DATA : oref TYPE REF TO cx_root.
TRY.
l_msgid_ref = param->get( if_mapping_param=>message_id ).
CATCH cx_sy_ref_is_initial INTO oref.
ENDTRY.
* Reading source XML data
DATA: odocument TYPE REF TO if_ixml_document.
DATA: root TYPE REF TO if_ixml_element.
DATA: msgid TYPE REF TO if_ixml_element.
DATA: person TYPE REF TO if_ixml_element.
DATA: name TYPE REF TO if_ixml_element.
DATA: fname TYPE REF TO if_ixml_node_collection.
DATA: lname TYPE REF TO if_ixml_node_collection.
DATA: bdate TYPE REF TO if_ixml_node_collection.
DATA: firstname TYPE REF TO if_ixml_node.
DATA: lastname TYPE REF TO if_ixml_node.
DATA: birthdate TYPE REF TO if_ixml_node.
DATA: fullname TYPE string.
DATA: str_fname TYPE string.
DATA: str_lname TYPE string.
DATA: fname_iterator TYPE REF TO if_ixml_node_iterator.
DATA: lname_iterator TYPE REF TO if_ixml_node_iterator.
DATA: bdate_iterator TYPE REF TO if_ixml_node_iterator.
DATA: ostream TYPE REF TO if_ixml_ostream.
DATA: renderer TYPE REF TO if_ixml_renderer.
DATA: rc TYPE i.
DATA: len TYPE i.
DATA: idx TYPE i.
fname = idocument->get_elements_by_tag_name( 'Name' ).
lname = idocument->get_elements_by_tag_name( 'Surname' ).
bdate = idocument->get_elements_by_tag_name( 'Birthdate' ).
* create output document
odocument = ixmlfactory->create_document( ).
* create a root node Names
root = odocument->create_simple_element(
name = 'PersonsCompact'
parent = odocument ).
* create element 'MessageID' and add it to the output document
msgid = odocument->create_simple_element(
name = 'MessageID'
value = l_msgid_ref
parent = root ).
* create iterators to iterate over the data elements
fname_iterator = fname->create_iterator( ).
lname_iterator = lname->create_iterator( ).
bdate_iterator = bdate->create_iterator( ).
len = fname->get_length( ).
idx = 0.
WHILE len GT idx.
idx = idx + 1.
* create element 'Person' and add it to the output document
person = odocument->create_simple_element(
name = 'Person'
parent = root ).
firstname = fname_iterator->get_next( ).
lastname = lname_iterator->get_next( ).
birthdate = bdate_iterator->get_next( ).
str_fname = firstname->get_value( ).
str_lname = lastname->get_value( ).
CONCATENATE str_fname str_lname INTO fullname SEPARATED BY space.
* create element 'Name' and add it to the output document
name = odocument->create_simple_element(
name = 'Name'
value = fullname
parent = person ).
* create element 'Birthdate' and add it to the output document
rc = person->append_child( birthdate ).
ENDWHILE.
* create output stream
ostream = streamfactory->create_ostream_xstring( result ).
* create renderer
renderer = ixmlfactory->create_renderer(
ostream = ostream
document = odocument ).
rc = renderer->render( ).
ENDMETHOD. "IF_MAPPING~EXECUTE
Implementing ABAP mapping in SAP PI
Once your ABAP Class is ready and activated, define a new interface mapping. Specify source and target message interfaces and click on Read Interfaces option. Under the Mapping Program section, select the Type as Abap-class (if this mapping type is not visible, you need to register the ABAP mapping type in Exchange profile). Under the name field, type the name of the ABAP class.
Save and activate the changes. Carry out rest of the configuration as usual and test your interface.