Skip to Content

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

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