cancel
Showing results for 
Search instead for 
Did you mean: 

IDOC Segment Mapping

Former Member
0 Kudos

Hi All,

We are running SAP PI 7.31 on a java only stack.  My scenario is IDOC to JDBC.  I am however battling with the Mapping in this scenario.

I am receiving an Enhanced IDOC and need to read the data from it.  The Specific segment I am battling with contains characteristics (A name and palue pair, see example below).  Basically the mapping I need to do is the following:

From:

<row>

          <ID>Name</ID>

          <Value>Renier</Value> 

</row>

<row>

          <ID>Surname</ID>

          <Value>Stasch</Value>

</row>

<row>

          <ID>Number</ID>

          <Value>123456789</Value>

</row>

To:

<Name>Renier</Name>

<Surname>Stasch</Surname>

<Number>123456</Number>

How can I do this?

I tried doing it with an ifWithoutElse and I tried writing my own function but I had no success.  Any suggestions will be welcomed.

Renier Stasch


Accepted Solutions (1)

Accepted Solutions (1)

ambrish_mishra
Active Contributor
0 Kudos

Ranier,

You can achieve the results through graphical mapping as well. You will need to write a java code for field population based on certain assumptions:

All the 3 source fields(Name, Surname and ID) are mandatory and will occur in sequence.

You have to create Target row(segment) once till the next occurrence of NAME tag with value NAME.

Target structure(IDoc segment) I assume would be like this.

Mapping for row:

For the field names, a user defined function (context) will be required to populate the target fields based on logic if NAME = "NAME", populate Value.

Pass an identifier for NAME, SURNAME and ID in each of them.

Hope it helps!

Ambrish

Message was edited by: Ambrish Mishra

Former Member
0 Kudos

Thanks for the reply Ambrish.

I however do not understand your solution.  I am not sure what I should put in my UDF or where I should use it.  I also see that you use Name in the Context of the structure and not in the row, is that correct.  

ambrish_mishra
Active Contributor
0 Kudos

Hi Renier,

first let me explain the solution:

The target node row will be created by the mapping outlined above in screenshot. So if the name/value pair comes for 3 fields, namely NAME, SURNAME and ID, you will have to create row at the target only once and you will create it again only when NAME with value of Name comes again for a different person from the source system.

For example, look at the test case below:

Is this your expected result. Currently I have not created the UDF for field population and have just put values manually in result but the target row is created based on mapping in my earlier post.

For this solution, you should know at design time as to how many possible fields will be coming from the source side. For example, I have assumed that NAME, SURNAME and ID will be coming from source. There might be more. say Age...

Then you will add Age under node root in the target but use the same logic above for creation of node row.

Coming back to your question....You should use the UDF to populate the target fields. So you need to loop around the values for element Name and check if it is a NAME, populate value from the result list and output the result to NAME in the target.

Similarly for other fields like Surname and ID.

Once the above is clear, we can move forward.

Hope it helps!

Ambrish

Former Member
0 Kudos

Hi Ambrish,

I followed your answers and did a lot of reading on the toppic and managed to get it working!  I am going to try and post as much of my solution as I can, maybe it will help someone else. Thanx a mil! 

  1. I basically created a UDF and changed the execution type to "All values as a context". 
  2. I added two Arguments, one for key and one for value.  These are passed as an array of strings
  3. Since there will be the same number of keys and values (an assumption I can make in my case), I looped through the array containing the keys, if the key was of type name (for example) I added the value to the resultList.
  4. I linked the value and key elements to my UDF in the mapping and the output to the relevant node. 
  5. I created one UDF for name, value and number

Here are the code in my UDF:

public void AssignValues(String[] key, String[] value, ResultList result, Container container) throws StreamTransformationException

{

     for(int j=0;j<key.length;j++)

     {

                                          if(key[j].equals("Name"))

                              {

                                                       result.addValue ( value [j] ); 

             }//end of if

     }

}

ambrish_mishra
Active Contributor
0 Kudos

Good that you understood the leads and tried the code.

Answers (2)

Answers (2)

manigram
Active Participant
0 Kudos

Hi,

Single payload consist of how many row tag only three or more then three , also share your target message structure.

Regards,

Manigandan

former_member184681
Active Contributor
0 Kudos

Hi Renier,

Have a look at the blog below by Sunil Chandra, it describes a solution to dynamically set target fields in mapping with UDF. This should perfectly solve your requirement.


Regards,

Greg

Former Member
0 Kudos

Thanks for the reply Greg!

I followed the steps in the link but the output I get is:

<row>

       <Name>Renier</Name>

</row>

<row>

       <surname>stasch</surname>

</row>

But the output I need is :

<row>

       <Name>Renier</Name>

       <surname>stasch</surname>

</row>

Any Suggestions?  I tried playing around with removing the context with no luck.