cancel
Showing results for 
Search instead for 
Did you mean: 

PI Mapping : Generating multiple nodes by one node

Former Member
0 Kudos

Hi,

I'm looking for the solution how to generate two nodes by one node in source messages. In the following sample messages, two nodes in source are expected to generate 4 nodes in output.

Source Structure

<item>

<id>

<name>

</item>

Target structure

<article>

<flag>

<id>

<name>

</article>

Source message instance

<item>

<id>1</id>

<name>ABC</name>

</item>

<item>

<id>2</id>

<name>XYZ</name>

</item>

Expected output message

<article>

<flag>QD</flag>

<id>1</id>

<name>ABC</name>

</article>

<article>

<flag>QI</flag>

<id>1</id>

<name>ABC</name>

</article>

<article>

<flag>QD</flag>

<id>2</id>

<name>XYZ</name>

</article>

<article>

<flag>QI</flag>

<id>2</id>

<name>XYZ</name>

</article>

In output message, two node of article 1 should be together.

Thanks in advance!

Victor

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Well I think for this you have to write UDF but before that you can try below solution and if doesn't help then go for UDF creation..

To get your desired restuls you have to duplicate the target structure once.

Right clik on <article> node and select "Duplicate Subtree". Now in first <article>-flag map constant "QD" and in in second map "QI", and map source <id> & <name> to target <id > & <name> nodes in both <article> nodes.

Former Member
0 Kudos

Thanks Sarvesh.

The solution you provide generates multiple nodes. However, it generates QD for item 1 and 2, then QI for item 1 and 2. I really need item 1 (QD/QI) then item 2 in output.

<article>

<flag>QD</flag>

<id>1</id>

<name>ABC</name>

</article>

<article>

<flag>QD</flag>

<id>2</id>

<name>XYZ</name>

</article>

<article>

<flag>QI</flag>

<id>1</id>

<name>ABC</name>

</article>

<article>

<flag>QI</flag>

<id>2</id>

<name>XYZ</name>

</article>

Thanks

Victor

Former Member
0 Kudos

Right.. so as I said before now we need to create UDF to retain the sequence of nodes.. give me some time and I will try to help you with UDF, But in mean time if some have some better ideas or UDF code reday they can share with you.

Former Member
0 Kudos

hi,

Create 2 UDF'S:

All values of a context, input will be var1

UDF1:

int a= var1.length;

int b=2*a;

for(int i=0;i<b;i++)

{

result.addValue("");

}

All values of a context, input will be var1

UDF2:

for(int i=0;i<2;i++)

{

result.addValue(var1[0]);

}

Mapping:

item-udf1-article

id-udf2-splibyvalue---id

nameudf2splitbyvalue-name

Note: Chk syntax errors if there are any..

Thanks

Amit

Former Member
0 Kudos

Here you go... basically the approach will same as said in my previous reply I mean first duplicate article node and then create just one UDF to map QD and QI to flag node..

Create UDF with Queue option and map the Item segment to UDF input and udf output to flag node..

for(int i=0;i<var1.length-1;i++)
{
result.addValue("QD");
result.addValue("QI");
}

Here are all mapping steps..

1. Item--->article (repeat the same mapping in 2nd article segment as well)

2. Item>UDF>SplitByValue-->Flag (repeat the same mapping in 2nd article segment as well)

3. Id >CopyValue(0)>Id (this is for 1st article segment)

4. Id >CopyValue(1)>Id (this is for 2nd article segment)

5. name >CopyValue(0)>name (this is for 1st article segment)

6. name >CopyValue(1)>name (this is for 2nd article segment)

Former Member
0 Kudos

I think above solution need some more correction.. I will update soon..

UPDATE:-

1. The fact is you need 3 UDFs

2. You don't need to duplicate the article.

So, for this and whole mapping steps and UDFs are as given below..

UDF1 (Cache:Queue) for Article node creation (this is taken from Amit's solution)

int a= var1.length;
int b=2*a;
for(int i=0;i<b;i++)
{
result.addValue("");
}

UDF2 (Cache:Queue) for FLAG node

for(int i=0;i<var1.length;i++)
{
result.addValue("QD");
result.addValue("QI");
}

UDF3 (Cache:Context) for name & id creation

int a= var1.length;
int b=2*a;

 for(int i=0;i<b;i++)
{
result.addValue(var1[0]);
}

Now here are the mapping steps..

1. Item ->UDF1->Article

2. Item>UDF2>SplitByValue--->Flag

3. Id->UDF3->SplitByValue--->Id

4. name->UDF3->SplitByValue--->name

Edited by: Sarvesh Singh on Dec 10, 2010 1:28 AM

Former Member
0 Kudos

The solution works. Thanks!

Former Member
0 Kudos

Hey thanks to all that contributed to the solution of this.

I'm a newby to message mapping of SAP PI.

But in my learning process I found out that the solution proposed in :

http://help.sap.com/saphelp_nw04/helpdata/en/26/d22366565be0449d7b3cc26b1bab10/content.htm

using the copyvalue function

is not working for the case where you have 2 partnernodes in the partnermsg. In this case the proposed solution is putting the street,city and zipcode of the first partnernode in both the targetnodes created in the mapping.

After some thinking about how to solve it I came up with the solution :

I created 3 UDF's ( getstreet ,getcity and getzipcode) :

public void getstreet(String[] var1, ResultList result, Container container) throws StreamTransformationException{

for (int i = 0; i < var1.length; i++) {

if ( (i%3) == 0) {

result.addValue(var1<i>);

}

}

}

public void getcity(String[] var1, ResultList result, Container container) throws StreamTransformationException{

for (int i = 0; i < var1.length; i++) {

if ( (i%3) == 1) {

result.addValue(var1<i>);

}

}

}

public void getzipcode(String[] var1, ResultList result, Container container) throws StreamTransformationException{

for (int i = 0; i < var1.length; i++) {

if ( (i%3) == 2) {

result.addValue(var1<i>);

}

}

}

the mapping for the target field street :

street = splitbyvalue ( getstreet(removecontext(addrdat)) "each value")

similar mappings need to be set for city and zipcode.

other mappings are :

customermsg = partnermsg

customer = createif(exists(partner)))

name = name

this solves the issue for the 2 partnernodes without using the copyvalue function

Answers (1)

Answers (1)

Former Member
0 Kudos

Hi,

Just Duplicate the target node "article" and then use copyValue function(JUST GIVE A TRY)

like: for first article:

id copyvalue(0)-id(target)

namecopyvalue(0)name(target)

similarly do it for the other "article" node:

id copyvalue(1)-id(target)

namecopyvalue(1)name(target)

Note: it would be better if u go for UDF.

Thanks

Amit