Skip to Content
Technical Articles
Author's profile photo Shabarish Nair

File Conversion using ‘Nodeception’

The Background Story:

 

The subject is of content conversion in the File Receiver Adapter. For those who have read the SAP help; it states that the adapter expects the XML to be of the below format;

<root>...
   <nameA>
         <value1>value</value1>
         <value2>value</value2>
         <value3>value</value3>
   </nameA>
   <nameB>
         <value4>value</value4>
   </nameB>
...
</root>...

So ideally, the adapter doesnt expect an XML with hierarchies???

The Scenario:

 

The expected output file format (taking a real time scenario from a utilities industry) needs to be as follows;

HEADER – Fields of Header (1-1)

(TRANSACTION –  Fields of Transaction

METERPOINT – Fields of Meter Point

ASSET – Fields of Asset

REGISTRATION –  Fields of Registration

READING – Fields of Reading)

TRAILER – Fields of Trailer (1-1)

A sample file output;

HEADR,H1,H2,H3

TRANS,T1,T11,T111

METER,M1,M11,M111

ASSET,A1,A11,A111

REGST,R1,R11,R111

READG,RD1,RD11,RD111

TRANS,T2,T22,T222

METER,M2,M22,M222

ASSET,A2,A22,A222

REGST,R2,R22,R222

READG,RD2,RD22,RD222

….

….

TRAIL, T1

NOTE: TRANS to READG segments will be a repeating set

The Design:

When we start the design, to suit the file content conversion the ideal Data Type would be as below;

image

The above exactly fits the expected XML format for the File adpater to perform content conversion.

Disaster strikes:

Using the above message structure in the mapping will reveal a glitch.

image

You would notice that all the TRANS, METER etc nodes are now collated together. But this is not what we want since we need first TRANS followed by the first METER and so on.

The above is due to a context issue. The truth is, I have never been able to figure out a context mapping to handle the above. Or maybe even if I might, would it prove to to be too much of an effort?

So this is what I propose;

Create your Data type as follows;

image

Carry on with your mapping. This time since we have introduced the BODY_NODE, it will ensure that the context is maintained.

The output of the mapping will now be;

image

Everything is as expected. Only thing pending is the File content conversion to create the output file.

NODECEPTION aka Node Deception:

To have the XML prepared as expected by the File adapter, we will use a simple trick I have come to call NODECEPTION = NODE + DECEPTION.

Why NODECEPTION?

Because, here we will trick (DECEPTION) the File adapter by removing the BODY_NODE node (NODE) from the XML and provide it with the structure as expected for content conversion.

Use the java code as per this link.

The Java code will remove all instances of the BODY_NODE tag from the XML.

Note: For PI 7.1, I have used parameterization to make the code dynamic and hence reusable. If using XI 3.0 or PI 7.0, you can remove the parameterization snippet from the code.

Add the java mapping in your operation mapping. You will have the java mapping executed after the original graphical mapping.

image

The output would be as below;

image

Now that we have the resulting XML as above, it’s simple FCC parameters that can create the output file.

The Next Steps:

The above ‘Nodeception’ method is what I found to be the easiest solution in such a scenario. Do you have a better and easier way? Or do you know how to manipulate the FCC parameters to handle hierarchy?

If you do, I request you to document your solution in this Wiki.

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Raghu Vamseedhar Reddy Kadipi Reddy
      Raghu Vamseedhar Reddy Kadipi Reddy
      I agree that, in this kind of situations, using two mappings (graphical mapping flowed by Java mapping or XSLT) will solve the issue easily. Similar situation would be, achieving 5 level hierarchies using FCC, which is not possible in one go, then we can use second mapping to insert that extra hierarchy required.  So, if the target structure is complex (cannot be achieved by one mapping), then: - convert to intermediate structure and then to final structure. I have seen people, in order to avoid two mappings (unknowingly) they start using one big complex Java mapping (DOM parser), which is risky to develop and maintain.
      Advantages: - As there is graphical mapping, we can see mapping logic easily (If it is one big Java mapping: - mapping logic is hidden).
      Disadvantage: - After every mapping payload is encoded, if there are more mapping back to back, that Operation mapping take more resource (affordable 🙂 ).
      Author's profile photo Vijayashankar Konam
      Vijayashankar Konam
      It was always a problem with the receiver adapter..!! Simple and nice solution..!!

      Vijay

      Author's profile photo Shabarish Nair
      Shabarish Nair
      Blog Post Author
      thanks.. one of the main objectives of this blog is also to find if we have better ideas to handle this structural limitations.

      Hope to see someone update the wiki with a smart solution 🙂

      ~~ShabZ

      Author's profile photo Tulasiram Donkena
      Tulasiram Donkena

      Hi Shabarish,

       

      Can you plz send me the Java code for above requirement. In your link it's not appearing.

       

      Plz send me the code asap to my email  id : ram.451donkena@gmail.com

       

      Thanks,

      Tulasiram

      7032822332

      Author's profile photo Former Member
      Former Member
      Could a newline character insertion (in the final phase) in dummy XML concatenated fields do the same trick? I have not tried it, but I often use 'nl' for separation in file receivers.
      Author's profile photo Arpil Gupta
      Arpil Gupta
      The trick shown in this weblog can be definitely handy... but the example cited can be handled using simple FCC.
      just have to use,
      Recordset Structure :: HEADR_NODE,TRANS,METER,ASSET,REGST,READG,TRIAL
      ... and the rest is simple.
      Author's profile photo Shabarish Nair
      Shabarish Nair
      Blog Post Author
      Thanks for the note.. yes it is possible using FCC.
      But the intention of this blog was to provide an alternative when dealing with deeper structures.
      Author's profile photo Attila Barcsik
      Attila Barcsik

      Thanks for the hint, I used your solution and it did exactly the same what the blog described using a Java mapping. It is more simple.

      Author's profile photo Former Member
      Former Member

      ... works perfectly. Thanx very much!!! You save a PI consultant's life today ... 🙂
      Regards,
      Volker

      Author's profile photo Shabarish Nair
      Shabarish Nair
      Blog Post Author

      glad to know 🙂

      Author's profile photo Stefan Grube
      Stefan Grube

      Instead of using FCC, you could use MessageTransformBean to do the conversion. The MessageTransformBean allows the target structure in your example directly.

      Unfortunately there is no good documentation for this. It works similar to the content conversion of the J2SE receiver file adapter.

      Regards

      Stefan

      Author's profile photo Adam Sosnowski
      Adam Sosnowski
      Instead of your Java mapping I prefer this simple XSLT, which does the same trick:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="node()">
        <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates/>
        </xsl:copy>
      </xsl:template>
      <xsl:template match="BODY_NODE">
        <xsl:apply-templates/>
      </xsl:template>
      </xsl:stylesheet>

      In order to remove more than one node from the hierarchy, just replicate the following part for each node, which needs to be removed:

      <xsl:template match="ANOTHER_NODE">

        <xsl:apply-templates/>

      </xsl:template>