cancel
Showing results for 
Search instead for 
Did you mean: 

PI Graphical Mapping with loops?

Former Member
0 Kudos

Hi!

I have the following Problem and would like to know if there is an elegant solution to it!

I want to map the Output of a function block to an XML structure. So there is nothing so Special about it

The Problem is the following:

In the source structure there are 2 tables:

Table1:

Field 1, Field 2

xyz     001

abc     002

Table2:

Field 1, Field 2, Field 3

mno     abc    001

abc     xyz     001

xyz     ako     002

A part of the target structure of the XML Looks like this:

<Tag1>

     <Subtag 1>001</Subtag1>

          --> Here All entries from Table 2 whose Field 3 corresponds to Field 2 of Table 1 should be placed!!

               <Tag2>

                    <Subtag2>mno</Subtag2>

                    <Subtag3>abc</Subtag3>

               </Tag2>

               <Tag2>

                    <Subtag2>abc</Subtag2>

                    <Subtag3>xyz</Subtag3>

               </Tag2>

     <Subtag 1>002</Subtag1>

               <Tag2>

                    <Subtag2>xyz</Subtag2>

                    <Subtag3>ako</Subtag3>

               </Tag2>

</Tag1>

Is there a solution to this by a graphical mapping?

BR, EF

Accepted Solutions (1)

Accepted Solutions (1)

markangelo_dihiansan
Active Contributor
0 Kudos

Hello Elmar,

This needs a UDF since Order_Suggestion contains two entries while Order_Suggestion_Option_Contains three entries in your example. You may use this mapping:

For Order_Suggestion:

For Suggested_Line/X_Feature_ID/Option/Sequential_No/

Now, for the Order_Suggestion_Option: There are two ways to map this

a. Use SplitByValue:ValueChanged

Cons of this is that you are not checking the input from Order_Suggestion-item-Suggested_Line

b. Via UDF

Cons, needs a user-defined function to work. UDF type is Context Type:

Arguments: inp1 type String[]

inp2 type String[]

for(int a=0;a<inp1.length;a++){

     int c=0;

     for(int b=0;b<inp2.length;b++){

          if(inp1[a].equals(inp2[c])){

               if(c+1<inp2.length){

                   if(inp1[a].equals(inp2[c+1])){

                        result.addValue(inp2[c]);

                    }

                    else if(!inp1[a].equals(inp2[c+1])){

                         result.addValue(inp2[c]);

                         result.addContextChange();

                    }

               }

               else{

                    result.addValue(inp2[c]);

               }

          }

     c++;

     }

}

Please forgive the unoptimized code.

Hope this helps

Mark

Former Member
0 Kudos

Hi!

First of all, thank you all for those numerous replies! I tried every solution and all of them work, but only for the first element ...

@Mark, i tried your solution A, but it just doesn't work ...

Result:

The other two entries are missing

markangelo_dihiansan
Active Contributor
0 Kudos

Hello Elmar,

Edit: The logic provided by Amit should work. Suggested_Line followed by a removeContext and sort and splitByValue:ValueChanged should create the Order_Suggestion_Option entries.

Regards,

Mark

Message was edited by: Mark Dihiansan

Former Member
0 Kudos

Hello! I also tried Amit's solution, as you can see here ... but i still only get 1 entry for 100 and 200. What happens to the other entries? There should be 2 for 100 and 2 for 200 ...

Result: The order_suggestion_options for 1-2 and 2-2 are missing ... it seems that the logic only processes the first element for 100 and 200 and then quits ;(

Former Member
0 Kudos

I attached another screenshot, so that you can exactly see the data that i used for the test! Only the first two elements in order_suggestion_option are processed ... 1-2 and 2-2 are missing!

Former Member
0 Kudos

Hello,

I think you are not changing the context of the fields?

Change the context of each source field (right click on field name -> context) and set it to MT** name

Thanks

Amit Srivastava

Former Member
0 Kudos

Hi Amit!

Now, i tried it like this, but it seems that the order_suggestion_option elements are not sorted! It seems to be one step closer to a solution, but something must still be wrong ...

Result:

Former Member
0 Kudos

Hello,

As stated previously u have to change the context of each and every source field (under order_suggested_option node).

In addition to that, the output of remove context will be the input to “SortByKey”.

Thanks

Amit Srivastava

Former Member
0 Kudos

Hi Amit!

I tried to Change the context of alle source fields, but i have three possibilites ... Standard was "item". I changed all source fields (Suggested_line, x_Feature_id, Option and sequence_no) to ORDER_SUGGESTION_OPTION. With NO success Then i tried the root node "Z_EXP_....", also with no success. Is there still something that i am doing wrong?

Former Member
0 Kudos

Hi Amit!

With your additional Input and a Little Change to the mapping, it works!!

Correct result:

Thanks to all, who tried to help me!!

BR, EF

Answers (6)

Answers (6)

Former Member
0 Kudos

At the Moment i tried the following, but it doesn't work ... the mapping does not put the Suggestion_options under the corresponding order_suggestion!

In the mapping, i check if the suggested_line fields are equal. If so, i try to put the whole order_suggestion_option element to the corresponding order_suggestion_option in the target structure ...

Here is the momentarily wrong result of the mapping ...

gagandeep_batra
Active Contributor
0 Kudos

Hi Elmar,

you can achive this by following logic

first use sort  function based on suggested_line and then you can use sortbykey &  split by change  value  function

Regards

Gagan

Former Member
0 Kudos

Hi!

I tried to realize your solution and it Looks better, but not entirely ...

Test data is the following:

   <ORDER_SUGGESTION>

      <item>

         <X_SUGGESTION_ID/>

         <DESCRIPTION/>

         <SUGGESTED_LINE>100</SUGGESTED_LINE>

      </item>

   <item>

         <X_SUGGESTION_ID/>

         <DESCRIPTION/>

         <SUGGESTED_LINE>200</SUGGESTED_LINE>

      </item>

   </ORDER_SUGGESTION>

   <ORDER_SUGGESTION_OPTION>

      <item>

         <X_FEATURE_ID>1-1</X_FEATURE_ID>

         <OPTION>1-1</OPTION>

         <SEQUENTIAL_NO>1-1</SEQUENTIAL_NO>

         <SUGGESTED_LINE>100</SUGGESTED_LINE>

      </item>

       <item>

         <X_FEATURE_ID>2-1</X_FEATURE_ID>

         <OPTION>2-1</OPTION>

         <SEQUENTIAL_NO>2-1</SEQUENTIAL_NO>

         <SUGGESTED_LINE>200</SUGGESTED_LINE>

      </item>

      <item>

         <X_FEATURE_ID>1-2</X_FEATURE_ID>

         <OPTION>1-2</OPTION>

         <SEQUENTIAL_NO>1-2</SEQUENTIAL_NO>

         <SUGGESTED_LINE>100</SUGGESTED_LINE>

      </item>

       <item>

         <X_FEATURE_ID>2-2</X_FEATURE_ID>

         <OPTION>2-2</OPTION>

         <SEQUENTIAL_NO>2-2</SEQUENTIAL_NO>

         <SUGGESTED_LINE>200</SUGGESTED_LINE>

      </item>

   </ORDER_SUGGESTION_OPTION>

But, there are items missing in the Output! Items 1-2 and 2-2 are missing at Level 100 or 200 ...

Former Member
0 Kudos

Hello,

U can refer below mapping for order_suggestion_option:

Note - i am assuming that values present in suggested_line under order_suggestion will always be there under order_suggestion_option-suggested_line

Thanks

Amit Srivastava

gagandeep_batra
Active Contributor
0 Kudos

Hi Elmar,

Plz you can chek below:

I am also amusing that value always present in suggestion is also present in suggestion-option

Regrads

gAgan

Former Member
0 Kudos

In the first Picture, you can see the source structure. Here, the Suggestion_option is on the same Level as order_suggestion. In the second Picture below, you can see the target structure, where the order_suggestion_option must be placed under the corresponding order_suggestion. My Problem is to find a solution where i can map the entries from order_suggestion_option with corresponding field suggested_line to the correct order_suggestion (where suggested_line must match). In the end, alle Suggestion_options with the same line number in "suggested_line" should reside directly under the corresponding order_suggestion as you can see in the second Picture!

Muniyappan
Active Contributor
0 Kudos

Hi Elmar,

if you can share your input and output xml it will be easier to suggest the solutions to you.

Regards,

Muniyappan.

iaki_vila
Active Contributor
0 Kudos

Hi Elmar,

I havent no clear your source sender. Are you using files for the sender adapter or it is a SOAP XML?. It depends how you had the XML sender structure for the difficulty of the message mapping.

Regards.

Former Member
0 Kudos

Hello,

Seems to be a straight forward requirement, but IMO, u should sort source values(using sortbykey) and then create ur target structure.

In case u want help more help on the mapping front then paste ur source XML here.

Thanks

Amit Srivastava

ambrish_mishra
Active Contributor
0 Kudos

Hi Elmar,

I think Tag2 should be a child of SubTag1?

You can use standard functions to achieve this.

Map  Table1 field2 (context Table1) to <SubTag1>

Map Table 2 field3 (context Table2) Split by value (Value Changed) to <Tag2>

for population of fields map fields directly from table 2.

Let me know if you are able to work it out else will quickly prototype it.

cheers,

Ambrish

PS: Based on assumption that table 1 and table 2 are sorted.