Hi dear experts,
After the first part:
1.- Develop and send your first outbound ABAP Proxy to SAP PI - for dummies part 1 of 3 of this complete interface:
2.- "We still implementing code in this second part" but now into SAP PI
3.- and after you end this post, you can test the complete scenario following the third post: Execute your SAP PI scenario from ABAP Proxy to PI (multimapping) to 2 receiver systems - for dummies part 3 of 3.
Objective: review the different mappings in one interface in an easy way for SAP PI consultants without expertise...
- Graphical Mapping,
- Java Mapping
- Simple,
- DOM,
- SAX,
- XSLT,
- XSL-ABAP (not implemented, just showing this optional mapping)
- ABAP Mapping
Flow: ABAP Proxy to SAP PI to XML File...
Version on 03/06/2015 --> Graphical and Easy Java Mapping..
Version on 04/06/2015 --> XSLT / Java Mapping DOM and pritty screen
Version on 08/06/2015 --> Java Mapping SAX / XSL-ABAP Mapping (optional)
Version on 09/06/2015 --> ABAP Mapping
Configuration:
1.- Operation Mapping:
In this part, you can see all the kind of mappings that we are using into one Operation Mapping, where the logic is to use each mapping after processing the last one, and when the xml arrive to the last mapping it means that is the result that is going to be delivered to the receiver system:
2.- Java Mapping - this logic will apply for Simple / DOM & SAX source codes:
After implement the code, you import the .JAR file into PI as "Imported Archive" object called here as IA_JM_TEST1_DIRECTLY:
After you upload your .JAR, with all the .class and .java files, you can visualize your source code, with double clic in .java files, for the same "imported archive" object:
Details:
1.- Graphical Mapping:
This kind of mapping, is recommended by SAP talking about performance and functional stantard, where you can map the sender and receiver metadata:
Even you can see the mapping related in this case:
2.- Java Mapping - SimplebyHow to create Java Mapping in SAP PI / PO:
After you have your "Imported archive" object, you can assign each java mapping into the operation mapping (in this case is the: "Proxy_2_Xml_JavaMapping.class" file:
If you follow the tutorial referenced, you can implement your first Java Mapping, where it just pass through without transformation or mapping:
package com.map; import java.io.*; import com.sap.aii.mapping.api.*; public class Proxy_2_Xml_JavaMapping extends AbstractTransformation { public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException { try { InputStream inputstream = transformationInput.getInputPayload().getInputStream(); OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream(); // Copy Input content to Output content byte[] b = new byte[inputstream.available()]; inputstream.read(b); outputstream.write("Prefixing this line to input. Proxy_2_Xml_JavaMapping. \r\n".getBytes()); outputstream.write(b); } catch (Exception exception) { getTrace().addDebugMessage(exception.getMessage()); throw new StreamTransformationException(exception.toString()); } } }
3.- Java Mapping - DOM by Java mapping with DOM and SAX parsers in new mapping API(PI 7.1) - Process Integration - SCN Wiki:
At same "Imported archive" object, you can find and assign the next java mapping into the operation mapping (in this case is the: "Proxy_PI_Xml_JavaDOM.class" file:
If you follow the tutorial referenced, you can implement your DOM Java Mapping, where it just pass through without transformation or mapping:
package com.map.dom; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Element; import com.sap.aii.mapping.api.AbstractTransformation; import com.sap.aii.mapping.api.MappingTrace; import com.sap.aii.mapping.api.StreamTransformationException; import com.sap.aii.mapping.api.TransformationInput; import com.sap.aii.mapping.api.TransformationOutput; public class Proxy_PI_Xml_JavaDOM extends AbstractTransformation { String result=""; //This is used in PI: private Map param = null; private MappingTrace trace = null; public void setParameter(Map param) { this.param = param; if (param == null) { this.param = new HashMap(); } } public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException { // String for constructing target message structure String fresult="<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; fresult = fresult.concat("<ns0:MT_TEST xmlns:ns0=\"urn:sia:test\">"); try{ InputStream inputStream = transformationInput.getInputPayload().getInputStream(); Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream); traversingXML(doc); } catch(Exception e){} fresult = fresult.concat(result); fresult = fresult.concat("</ns0:MT_TEST>"); try{ transformationOutput.getOutputPayload().getOutputStream().write(fresult.getBytes()); /* assigning the created target message to "TransformationOutput"*/ } catch(IOException e1){} } //4.- With the last point 3 we will start the transformation and extract the result public void traversingXML(Node node){ NodeList children = node.getChildNodes(); for(int i=0;i<children.getLength();i++) { Node child = children.item(i); short childType = child.getNodeType(); if(childType==Node.ELEMENT_NODE) { String nodeName=child.getNodeName(); String targetNodeName=null; if(nodeName.equals("ITEM1")) targetNodeName="ITEM1"; else if(nodeName.equals("ITEM2")) targetNodeName="ITEM2"; else if(nodeName.equals("ROW")) targetNodeName="ROW"; if(targetNodeName!=null) result=result.concat("<"+targetNodeName+">"); traversingXML(child); if(targetNodeName!=null) result=result.concat("</"+targetNodeName+">"); } else if(childType==Node.TEXT_NODE) { String nodeValue = child.getNodeValue(); result = result.concat(nodeValue); } } } }
4.- Java Mapping - SAX by Java mapping with DOM and SAX parsers in new mapping API(PI 7.1) - Process Integration - SCN Wiki:
At same "Imported archive" object, you can find and assign the next java mapping into the operation mapping (in this case is the: "Proxy_PI_Xml_JavaSAX" file:
If you follow the tutorial referenced, you can implement your SAX Java Mapping, where it just pass through without transformation or mapping:
package com.map.sax; import java.io.InputStream; import java.io.IOException; import com.sap.aii.mapping.api.AbstractTransformation; import com.sap.aii.mapping.api.TransformationInput; import com.sap.aii.mapping.api.TransformationOutput; import com.sap.aii.mapping.api.StreamTransformationException; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.SAXException; import org.xml.sax.Attributes; public class Proxy_PI_Xml_JavaSAX extends AbstractTransformation { /* 1.- DONT NEED TO MODIFY ANYTHING*/ public void transform(TransformationInput in,TransformationOutput out) throws StreamTransformationException{ InputStream instream = in.getInputPayload().getInputStream(); Handling handler= new Handling(); SAXParserFactory factory = SAXParserFactory.newInstance(); String result=null; try{ SAXParser saxpr = factory.newSAXParser(); saxpr.parse(instream,handler); } catch(Exception e){e.printStackTrace();} result=handler.getResult(); try{ out.getOutputPayload().getOutputStream().write(result.getBytes()); } catch(IOException e){} } } /* Second class Which extends DefaultHandler*/ class Handling extends DefaultHandler { public String fresult = null; public void startDocument() throws SAXException { /* 2.- Here add the heather of your XML output*/ fresult="<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; fresult = fresult.concat("<ns0:MT_TEST xmlns:ns0=\"urn:sia:test\">"); } /* 3.- Here add the end node of your XML, to close the point 2 of the heather*/ public void endDocument() throws SAXException { fresult=fresult.concat("</ns0:MT_TEST>"); } /* 4.- Here add the nodes of your XML, TO OPEN EACH ONE*/ public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException { String lName = localName; if(lName.equals("")) lName=qName; if(lName.equals("ITEM1")) fresult=fresult.concat("<ITEM1>"); if(lName.equals("ITEM2")) fresult=fresult.concat("<ITEM2>"); if(lName.equals("ROW")) fresult=fresult.concat("<ROW>"); } /* 5.- Here add the nodes of your XML, TO CLOSE the nodes added in point 4*/ public void endElement(String namespaceURI, String localName,String qName) throws SAXException { String lName = localName; if(lName.equals("")) lName=qName; if(lName.equals("ITEM1")) fresult=fresult.concat("</ITEM1>"); if(lName.equals("ITEM2")) fresult=fresult.concat("</ITEM2>"); if(lName.equals("ROW")) fresult=fresult.concat("</ROW>"); } public void characters(char[] ch, int start, int length) throws SAXException { String val= new String(ch,start, length); fresult=fresult.concat(val); } public String getResult() { return fresult; } }
5.- XSLT Mapping:
Now, you can see other mapping supported in PI, where in this case is one of the last kind of mappings recomended by SAP; in this logic, you get all the "ROW" nodes and with flexibility you can adapt it to your future solutions (you can implement in different softwares as Stylus Studio, before to import it in PI):
<?xml version="1.0" encoding="utf-8"?><!--Created by Azael Navarro Jimenez Email: azaelnjim1988@hotmail.com Date: 04/06/2015--><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" omit-xml-declaration="yes"/><xsl:template match="/"><xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="utf-8"?>]]></xsl:text><ns0:MT_TEST xmlns:ns0="urn:sia:test"> <!--For each row, we can add their values--> <xsl:for-each select="//ROW"> <ROW> <!--The values of each row--> <ITEM1><xsl:value-of select="ITEM1"/></ITEM1> <ITEM2><xsl:value-of select="ITEM2"/></ITEM2> </ROW> </xsl:for-each></ns0:MT_TEST></xsl:template></xsl:stylesheet>
Then similar as Java mapping, you can attach your ZIP file where contain your XSL file, and you can import it in PI into "Imported Archive" object:
You have the option to see your XSLT in a graphical way, into PI:
Even, you can see the source code into PI:
After that, you just need to assign it into the Operation Mapping in PI:
6.- XSLT-ABAP Mapping (was not implemented, i just show you this optional mapping):
In this mapping we are not going to include it into this exercise because i don't have persmission as a developer, but i show you that you have the option to implement it directly in ABAP side of PI and then called from operation mapping using the transaction (XSLT_TOOL) or even using ABAP code mixed with XSLT code in other transactions proposed in documentation as: http://www.sapwiki.cl/wiki/images/8/89/ABAP252_exercises_XSLT_XML.pdf:
And choose the class:
And implement the similar code as shown in step 5:
Modifying just the "transformation" node:
<!--Created by Azael Navarro Jimenez Email: azaelnjim1988@hotmail.com Date: 08/06/2015--><xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" version="1.0"> <xsl:output method="xml" omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:text disable-output-escaping="yes"><?xml version="1.0" encoding="utf-8"?></xsl:text> <ns0:MT_TEST xmlns:ns0="urn:sia:test"> <!--For each row, we can add their values--> <xsl:for-each select="//ROW"> <ROW> <!--The values of each row--> <ITEM1><xsl:value-of select="ITEM1"/></ITEM1> <ITEM2><xsl:value-of select="ITEM2"/></ITEM2> </ROW> </xsl:for-each> </ns0:MT_TEST> </xsl:template></xsl:transform>
Then test it:
C:\Users\Azael \Desktop \Mappings\ABAP XSLT\2 XML test\test.xml
1.- Let you print the result as string:
2.- Let you export a file with the result:
C:\Users\Azael \Desktop\Mappings\ABAP XSLT\2 XML test\out.xml
Try to implement it into the operation mapping (REMEMBER THAT THIS WAS NOT TESTED DIRECTLY, so you need to test this method or implement another method in order to implement XSL from ABAP side):
7.- ABAP Mapping (please refer to the ABAP Mapping "references" below to more details):
Now we are going to implement an easy transformation logic, that maybe you can find already implemented into your PI, but if not just follow this logic (please refer other documentation to especialized your profile in this topic):
1.- In transaction se80, look for IF_MAPPING Class / Interfaces, then double clic in EXECUTE section:
Implement the code:
method IF_MAPPING~EXECUTE . trace->trace1( 'Start of Application Mapping CL_COPY_MAPPING' ). "#EC NOTEXT result = source. trace->trace1( 'End of Application Mapping CL_COPY_MAPPING' ). "#EC NOTEXT endmethod.
2.- Then add the name of your class into the operation mapping:
IMPORTANT: go "below of this post" to the references links in ABAP mapping section, because maybe you need to follow some other steps to configure your PI.
Testing our 6 Mappings in just one interface:
In the test you can use the following metadata - Input:
<?xml version="1.0" encoding="UTF-8"?><ns0:MT_TEST xmlns:ns0="urn:sia:test"> <ROW> <ITEM1>Azael</ITEM1> <ITEM2>26</ITEM2> </ROW> <ROW> <ITEM1>Jorge</ITEM1> <ITEM2>32</ITEM2> </ROW></ns0:MT_TEST>
Result:
<?xml version="1.0" encoding="utf-8"?><ns0:MT_TEST xmlns:ns0="urn:sia:test"> <ROW> <ITEM1>Azael</ITEM1> <ITEM2>26</ITEM2> </ROW> <ROW> <ITEM1>Jorge</ITEM1> <ITEM2>32</ITEM2> </ROW></ns0:MT_TEST>
The result must be the same, for each mapping and for the whole Mapping Test:
I hope you can enjoy it!...
References:
A. About Java Mappings:
Primary:
http://scn.sap.com/docs/DOC-45642
**************** - Understanding Java Mapping concepts
How to create Java Mapping in SAP PI / PO - using DOM parser
Secondary:
Implementing a Java Mapping in SAP PI
XI AF API call failed. Module exception: Java Mapping
Java mapping with DOM and SAX parsers in new mapping API(PI 7.1) - Process Integration - SCN Wiki
How to DOM Parsing JAVA Mapping in SAP PI 7.3 | SCN
Write Java Mapping directly in ESR!
How to read XML file in Java &#8211; (DOM Parser)
B. About XSLT:
Useful XSLT mapping functions in SAP XI/PI
Transformation Editor - Application Development on AS ABAP - SAP Library
http://www.sapwiki.cl/wiki/images/8/89/ABAP252_exercises_XSLT_XML.pdf
Generate Simple Transformation for XML in ABAP - Part II | &#169; Passionate about SAP - A Blog
C. About ABAP Mapping:
1.- Principal:
How to register ABAP Mapping in SAP PI Exchange Profile
ABAP Mapping in SAP PI - A Beginner Guide
ABAP Mapping in SAP PI: A Complete Code Walkthrough
2.- Secondary:
ABAP Mapping Steps - Process Integration - SCN Wiki
ABAP Mappings - Enterprise Services Repository - SAP Library
Exchange Infrastructure - Understanding and working with ABAP Mapping