Skip to Content

Many times, you are required to convert flat file structures to deeply nested structures like IDocs. Standard File Content Conversion allows you to convert the incoming file to flat XML structures only i.e. only one level of nesting is possible. Converting incoming file to deeply nested structures would require use of either custom developed adapter modules/Java mappings or third-party conversion agents or inbuilt graphical mapping by using intermediate structures and user defend functions.


Simplest way of achieving these kind of requirements is by using SAX parser. Below are the pros and cons for the same.


Pros:

  • When compared to other Java parsers like DOM, JAXB; Complexity of the code wise SAX is the best suitable option for this kind of requirements.
  • When compared to graphical mapping; No need of inserting intermediate structure and complex context handling logics and user defined functions.
  • SAX is much faster and less memory usage than its counterpart DOM parser

Cons:

  • Numbers of Lines of code increases when numbers of fields are more.

Step-By-Step Directions to build in SAP PI:

Step1:

Develop the customized Java mapping code in NWDS and import the jar file into ESR as an archival object.

Below is the code written for Java Mapping.

package com.sappi.practice;

///Normal Java Imports

import java.io.IOException;

import java.io.InputStream;

//SAX imports

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

//Java Mapping Imports

import com.sap.aii.mapping.api.AbstractTransformation;

import com.sap.aii.mapping.api.StreamTransformationException;

import com.sap.aii.mapping.api.TransformationInput;

import com.sap.aii.mapping.api.TransformationOutput;

//Below program is written using PI 7.1 API

public class HierarchialStructuresUsingSAX extends AbstractTransformation {

    public void transform(TransformationInput in, TransformationOutput out)

            throws StreamTransformationException {

        getTrace().addInfo(“JAVA Mapping Called”);

        InputStream instream = in.getInputPayload().getInputStream();

        getTrace().addInfo(“Input XML Payload is successfuly Read”);

        Handling handler = new Handling();

        SAXParserFactory factory = SAXParserFactory.newInstance();

        String result = null;

        try {

            SAXParser saxpr = factory.newSAXParser();

            saxpr.parse(instream, handler);

        } catch (Exception e) {

            getTrace().addWarning(“$$$ Exception occured $$$” + e.getMessage());

            e.printStackTrace();

            getTrace().addInfo(e.getMessage(), e);

        }

        result = handler.getResult(); //Getting the final Output Structure

        try {

            out.getOutputPayload().getOutputStream().write(result.getBytes());

            getTrace().addInfo(“Output XML Payload is successfuly Written”);

        } catch (IOException e) {

            getTrace().addWarning(

                    “$$$ Exception occured while writing the o/p payload $$$”);

            e.printStackTrace();

            getTrace().addInfo(e.getMessage(), e);

        }

    }

    /* Second class Which extends DefaultHandler */

    class Handling extends DefaultHandler {

        StringBuffer fresult = new StringBuffer();

        private String ITEM_Node = “closed”;

        private String ItemDetail_Node = “closed”;

        public void startDocument() throws SAXException {

            fresult.append(“<?xml version=\”1.0\” encoding=\”UTF-8\”?>”);

            fresult.append(“<ns0:ReceiverFile_MT xmlns:ns0=\”Test\”>”);

        }

        public void endDocument() throws SAXException {

            fresult.append(“</ns0:ReceiverFile_MT>”);

        }

        public void startElement(String namespaceURI, String localName,

                String qName, Attributes atts) throws SAXException {

            String lName = localName;

            if (lName.equals(“”))

                lName = qName;

            if (lName.equals(“HEADER”)) {

                fresult.append(“<HEADER>”);

            }

            if (lName.equals(“CREATION_DATE”)) {

                fresult.append(“<CREATION_DATE>”);

            }

            if (lName.equals(“CREATION_TIME”)) {

                fresult.append(“<CREATION_TIME>”);

            }

            if (lName.equals(“ITEM”)) {

                if (ItemDetail_Node.equalsIgnoreCase(“open”)) {

                    fresult.append(“</ItemDetail>”);

                    ItemDetail_Node = “closed”;

                }

                if (ITEM_Node.equalsIgnoreCase(“open”)) {

                    fresult.append(“</ITEM>”);

                    ITEM_Node = “closed”;

                }

                fresult.append(“<ITEM>”);

                ITEM_Node = “open”;

            }

            if (lName.equals(“OrderNumber”)) {

                fresult.append(“<OrderNumber>”);

            }

            if (lName.equals(“ItemDetail”)) {

                if (ItemDetail_Node.equalsIgnoreCase(“open”)) {

                    fresult.append(“</ItemDetail>”);

                    ItemDetail_Node = “closed”;

                }

                fresult.append(“<ItemDetail>”);

                ItemDetail_Node = “open”;

            }

            if (lName.equals(“OrderQualtity”)) {

                fresult.append(“<OrderQualtity>”);

            }

            if (lName.equals(“TotalCost”)) {

                fresult.append(“<TotalCost>”);

            }

            if (lName.equals(“Address”)) {

                fresult.append(“<Address>”);

            }

            if (lName.equals(“HouseNumber”)) {

                fresult.append(“<HouseNumber>”);

            }

            if (lName.equals(“Street”)) {

                fresult.append(“<Street>”);

            }

            if (lName.equals(“PostCode”)) {

                fresult.append(“<PostCode>”);

            }

            if (lName.equals(“Trailer”)) {

                if (ItemDetail_Node.equalsIgnoreCase(“open”)) {

                    fresult.append(“</ItemDetail>”);

                    ItemDetail_Node = “closed”;

                }

                if (ITEM_Node.equalsIgnoreCase(“open”)) {

                    fresult.append(“</ITEM>”);

                    ITEM_Node = “closed”;

                }

                fresult.append(“<Trailer>”);

            }

            if (lName.equals(“NoofRecords”)) {

                fresult.append(“<NoofRecords>”);

            } // Says No of ITEM Records

        }

        public void endElement(String namespaceURI, String localName,

                String qName) throws SAXException {

            String lName = localName;

            if (lName.equals(“”))

                lName = qName;

            if (lName.equals(“HEADER”)) {

                fresult.append(“</HEADER>”);

            }

            if (lName.equals(“CREATION_DATE”)) {

                fresult.append(“</CREATION_DATE>”);

            }

            if (lName.equals(“CREATION_TIME”)) {

                fresult.append(“</CREATION_TIME>”);

            }

            if (lName.equals(“OrderNumber”)) {

                fresult.append(“</OrderNumber>”);

            }

            if (lName.equals(“OrderQualtity”)) {

                fresult.append(“</OrderQualtity>”);

            }

            if (lName.equals(“TotalCost”)) {

                fresult.append(“</TotalCost>”);

            }

            if (lName.equals(“Address”)) {

                fresult.append(“</Address>”);

            }

            if (lName.equals(“HouseNumber”)) {

                fresult.append(“</HouseNumber>”);

            }

            if (lName.equals(“Street”)) {

                fresult.append(“</Street>”);

            }

            if (lName.equals(“PostCode”)) {

                fresult.append(“</PostCode>”);

            }

            if (lName.equals(“Trailer”)) {

                fresult.append(“</Trailer>”);

            }

            if (lName.equals(“NoofRecords”)) {

                fresult.append(“</NoofRecords>”);

            }

        }

        public void characters(char[] ch, int start, int length)

                throws SAXException {

            String val = new String(ch, start, length);

            fresult.append(val);

        }

        public String getResult() {

            return fresult.toString();

        }

    }

}

Step2:

Build an interface which picks the csv file from System A and transform into target hierarchical structure using the importing java archive in the previous step and post the Output (File, IDoc, etc) into target system B.


  Sample Input CSV File

Input.jpg

Input XML payload after FCC.

InputXML.jpg

Output XML Payload:

OutXML.jpg

Regards

Venkat

To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Former Member

    Hi Venkat,

    Thanks for the info, the blog waht u have posted is really helpful, but i need some more info., weather this works for multiple records in a single file

    (0) 
    1. Former Member Post author

      Thanks Praveen.

      Yes it works .Example I have taken to explain does contain multiple body records in a single file .

      Regards

      Venkat

      (0) 
  2. Sara Schmidt

    Hi Gurus,

    i have no much experiences with Java and I want to simulate this example by myself.

    However I do not understand it clearly.

    This Java mapping should be put in an Operation mapping, shouldn’t it?

    If so, how can i define this service-Interface and message-type inside?

    your Explanation would be appreciated.

    Sincerely

    Sara

    (0) 
    1. Former Member

      Hi Sara,

      Can you create separate thread and give the input file and output XML which you expecting it then we can take it from there.

      Regards,

      Praveen.

      (0) 
      1. Sara Schmidt

        Hi Praveen,

        thank you for your reminder!

        I think it is not neccessary to create a new thread.

        I just want to know how this example works without FCC.

        thanks and regards

        Sara

        (0) 
        1. Manoj Kh

          FCC is needed , FCC converts the flat file to one level XML file and then java mapping is used to convert the one level xml to deeply nested structure.

          (0) 

Leave a Reply