Skip to Content
Author's profile photo Former Member

Simplest way to Convert Flat File to Deeply Nested XML Structures Using Java Mapping

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

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Iñaki Vila
      Iñaki Vila

      Hi Venkat,

      You are helping all the community with a typical problem in the forums. Thanks for sharing!.

      Regards.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thank you... 🙂

      Author's profile photo Rajeev Goswami
      Rajeev Goswami

      Nice blog!!

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thanks Rajeev.

      Author's profile photo praveen kumar
      praveen kumar

      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

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thanks Praveen.

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

      Regards

      Venkat

      Author's profile photo Former Member
      Former Member

      Nice informative blog Venkat.

      Thanks.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thank you Anshu Kumar.

      Author's profile photo Avinash Ayanala
      Avinash Ayanala

      Hi Venkat,

      It is very informative blog thanks for sharing your knowledge.

      Regards,

      Avinash

      Author's profile photo Former Member
      Former Member

      Hi Venkat,

      Thank you for sharing this.  It really helped.

      Regards,

      Santhi

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thank you .I'm glad my blog helped.

      Regards

      Venkat

      Author's profile photo Sara Schmidt
      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

      Author's profile photo Praveen Gandepalli
      Praveen Gandepalli

      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.

      Author's profile photo Sara Schmidt
      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

      Author's profile photo Manoj K
      Manoj K

      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.

      Author's profile photo Sara Schmidt
      Sara Schmidt

      Aha. That accounts for it!

      thanks for the Explanation! I'm too foolish. 😛

      Author's profile photo Former Member
      Former Member

      Hi Venkat,

      Help full blog, could you please give me screenshot of your FCC