Skip to Content

Many a times, you are required to convert flat file structures to deeply nested structures like IDocs. StandardFile 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 or third-party conversion agents.

This article provides a workaround to accomplish the same thing by using only the graphical mapping. William had a similar requirement, and we came up with a generic solution which is described below.

Lets say we have an incoming flat file with structure as described below –

    Node1 – Occurs 0..1
    Node2 – Occurs 0..unbounded
    Node3 – Occurs 0..unbounded
    Node4 – Occurs 0..unbounded

And the target structure is as shown below –

    Node1 – Occurs 0..1
    Node2 – Occurs 0..unbounded
    Node3 – Occurs 0..unbounded and repeats under the preceding Node2
    Node4 – Occurs 0..unbounded and repeats under the preceding Node3

!http://www.riyaz.net/blog/wp-content/uploads/2008/05/fcc-flat-xml-150×150.jpg|title=File Content Conversion (Click to enlarge)|height=150|style=border: 0pt none ; float: right; margin-left: 5px; margin-right: 5px|alt=File Content Conversion|width=150|class=alignright alignnone size-thumbnail wp-image-265|src=http://www.riyaz.net/blog/wp-content/uploads/2008/05/fcc-flat-xml-150×150.jpg!Due to limitation of the standard File adapter, it is not possible to directly convert the incoming file to the deeply nested target structure. Hence we will use a two step message mapping to attain the required result.

First, we will use file content conversion as shown to covert the incoming file to flat XML structure as supported by the adapter. Click the image on the right to see an enlarged view. We will then use two-step message mapping to convert the flat XML to a nested XML. Figure below shows the flat XML structure generated by the file adapter using file content conversion.

Source Message

Our aim is to convert the above flat structure to a nested shown below –

Target Message

Note that there is no common element between parent and child nodes (e.g. Node2 and Node3, or Node3 and Node4) which we could use to determine corresponding parent node for each child node.

Hence, we need to create an intermediate message type which will establish a relationship between the parent and child nodes. We have achieved this by adding id attributes to each of the nodes as shown below.

Intermediate Message

The id attribute is mapped using a user defined function globalCounter which records the order in which the nodes appear in the source structure. The variable used to store the count is a global variable and is incremented every time a node is found in the source structure (irrespective of the node name).

Create one-to-one message mapping between source message and the intermediate message. Map the id attribute in the target with the globalCounter function.

globalcounter UDF

The Java code of the globalCounter function is given below –

    public String globalCounter(Container container){
   
    GlobalContainer globalContainer;
   
    globalContainer = container.getGlobalContainer();
    Object o = globalContainer.getParameter(“count”);
    Integer i;
   
    if ( o == null ) i = new Integer( 0 );
    else i = (Integer)o;
   
    i = new Integer(i.intValue() + 1 );
    globalContainer.setParameter(“count”, i );
   
    return i.toString();
    }

Now create another message mapping to map the intermediate message type to the target message type. The message mapping is shown below.

Message Mapping

Node 1 is directly mapped to Node1 in the target as this node is not part of any hierarchy. The topmost parent node Node2 is mapped using removeContexts function.

First node mapping

All the nodes appearing below the topmost node (Node3 and Node4 in this case) have been mapped using removeContexts function and user defined nest function as shown below –

!http://www.riyaz.net/blog/wp-content/uploads/2008/05/child-node-mapping.jpg|title=Child node mapping using UDF nest|height=116|alt=Child node mapping using UDF nest|width=400|class=alignnone size-full wp-image-264|src=http://www.riyaz.net/blog/wp-content/uploads/2008/05/child-node-mapping.jpg!

The first parameter to the nest function is the id attribute of the parent node while the second parameter is the id attribute of the current node (child node). Both parameters have been first processed with removeContexts function before passing them to the nest function. The third parameter is the actual value of the node that needs to passed on to the target structure. Below is the Java code for the nest function.

    public void nest(String[] parent,String[] current,String[] node,ResultList result,Container container){
   
    int i, j;
    int a, b, c;
    int x;
   
    j = 0;

    x = j1;<br />    for( i = 0; i < current.length; i+ ) {
        for (;x<parent.length; j+,x+ ){
            a = Integer.parseInt(parent );
            b = Integer.parseInt(current );
            c = Integer.parseInt(parent );
            if ( a < b ) {
                if(c > b ) {
                    result.addValue(node[i]);
                    break;
                    }
                else if (c < b) {
                    result.addContextChange();
                    }
                }
            }
        if (x == parent.length) {
            result.addValue(node[i]);
            }
        }
    }

PS: If you are new to the idea of context handling, do read An Introduction to Context Handling.

Once this is done, create an interface mapping between the source and target interface and provide the mapping programs in the correct order i.e. first the mapping between source and intermediate message and then the one between intermediate and target structure. The same is shown below –

Interface Mapping with Two-step Message Mapping

Now you can test the interface mapping locally and then test your scenario by doing appropriate directory configuration. Interface mapping test result is shown in the figure below –

!http://www.riyaz.net/blog/wp-content/uploads/2008/05/im-test-result.jpg|title=Test Result|height=270|alt=Test Result|width=400|class=alignnone size-full wp-image-269|src=http://www.riyaz.net/blog/wp-content/uploads/2008/05/im-test-result.jpg!

Thus, we have seen how we can use plain file adapter and graphical mapping to convert a flat file to a deeply nested XML structure.

This idea could even be extended to convert EDI documents to IDoc structures as an alternative to third-party EDI adapters like Seeburger.

To report this post you need to login first.

8 Comments

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

  1. Dijesh Tanna
    Hello Riyaz,

    good written blog , however technically I don’t see anything new in that. This is the traditional approach that everyone is taking and even it’s much simpler if you use XSLT mapping.

    Also the main reason for using conversion agent and SeeBurger is that EDI standard are very complex and in large no, and both this tools provides library for all the EDI stanradrd. That’s why effort should not be put in parsing that complex structure.

    (0) 
    1. Riyaz Sayyad Post author
      Hi Dijesh,

      I agree with you and appreciate your point of view.

      Seeburger certainly has its advantages as you dont need to worry about structure complexity and also as the EDI standards evolve or get modified, Seeburger delivers new objects/patches that can be readily integrated.

      At the same time note that some clients may not want to invest into Seeburger if all they need it for is a single scenario/process.

      Regards,
      Riyaz

      (0) 
  2. Gopalakrishna Kurapati
    Hi Riyaz, Nice blog and trying to fit it for my scenerio. I am working on a scenerio for which source is mainframe file to Idoc Order05. I tried applying the above logic. It worked fine, but not exactly fit into my scenerio. My scenerio needs parent node “node1” should be 0 to unbound.
    Node1 – Occurs 0..unbounded
    Node2 – Occurs 0..unbounded

    Can you suggest modification to your code? I appreciate your help in this regard.

    Thanks
    Krish

    (0) 
    1. Riyaz Sayyad Post author
      Hi Krish,

      In my case Node1 is out of the hierarchy. Only Node2, Node3 and Node4 are nested under one another. And all the three are 0..unbounded. So I guess this solves your problem.

      Let me know if I did not understand your concern correctly.

      Thanks.

      Regards,
      Riyaz

      (0) 
  3. Ishwarya H
    Hi Riyaz,
    I have a deep structure in my input flat file.
    Something like this-
    RecSet
    |_Rec1
    |_Rec2
    |_BatchGroup(1:unbounded)
    ……… |_DetailGroup(1:unbounded)
    ………………|_Rec3
    ………………|_Rec4(1:unbounded)
    ……….|_BatchTotal
    |_Rec5
    |_Rec6

    Is there an alternative to developing an adapter module specifically for this purpose since this cannot be handled in File content conversion of file adapter in PI?
    Thanks.

    (0) 
  4. shameer shaik

    Hi Riyaz,

    Excellent blog.

    I have similar requirement and trying with XSLT. I am facing issue when converting linear to deep structures in the inner loops.

    Example:

    Node3 – Occurs 0..unbounded and repeats under the preceding Node2.

    When I have written For each loop for Node3.All Node3 nodes are getting repeated in each record instead of one for each record.

    Could you please help me hoe to handle inner loops in XSLT

    (0) 

Leave a Reply