cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple Mapping Again

Former Member
0 Kudos

Source Structure1:<?xml version="1.0" encoding="UTF-8"?>

<E_Students> Occurrence 1...1

|----<Student> Occurrence 1...Unbounded

|----


<ID> Occurrence 1...1

|----


<Name> Occurrence 1...1

|----


<Gender> Occurrence 1...1

Source Structure2:

<?xml version="1.0" encoding="UTF-8"?>

<C_Students> Occurrence 1...1

|----<Student> Occurrence 1...Unbounded

|----


<Index> Occurrence 1...1

|----


<Name> Occurrence 1...1

|----


<Sex> Occurrence 1...1

Target Structure:

<?xml version="1.0" encoding="UTF-8"?>

<Students> Occurrence 1...1

|----<Student> Occurrence 1...Unbounded

|----


<ID> Occurrence 1...1

|----


<Name> Occurrence 1...1

|----


<Gender> Occurrence 1...1

For my issue, I want to map E_Students.student.id to Students.student.id, E_Students.student.Name to Students.student.Name, but with a rule that if E_Students.student.Gender has value, map this value to Students.student.Gender, otherwise map C_Students.student.Sex to Students.student.Gender with the condition that if the value of C_Students.student.Index is the same as E_Students.student.ID. what's more, there is no guaranted ordering between these two source xml.

in my true scenario, these three xml structure is very big, and just have several elements need mapping rule like "Gender" element. who can provide me any mapping solution? hope from your help:)

Message was edited by: Spring Tang

Message was edited by: Spring Tang

Specify that there are no predefined order in these two source xml files.

Message was edited by: Spring Tang

change C_Students.student.ID to C_Students.student.Index

Accepted Solutions (1)

Accepted Solutions (1)

former_member187339
Active Contributor
0 Kudos

Hi,

Assumption only either of sex or gender exists for a given id ...

try this

ID(context E_Students)----


|

Index(context C_Students)----


| createGender SplitbyValueGender

Gender(context C_Students)CollapseContext|

Sex (context E_Students)--CollapseContext|

Here createGender is a UDF:

<b>

public void createGender(String[] ID,String[] C_ID,String[] Gender,String[] Sex,ResultList result,Container container)

{

int k=0, j=0;

for (k=0;k<ID.length;k++)

{

for (j=0;j<C_ID.length;j++)

{

if (ID[k].equals(C_ID[j]))

{

if (!Gender[j].equals ("") )

result.addValue(" "+Gender[j]);

else

result.addValue(" "+Sex[k]);

}

}

}

}</b>

For ID and name do 1..1 mapping

collapseContext and SplitbyValue are node functions.

Regards

Suraj

Message was edited by: S.R.Suraj

Was the problem solved???

Former Member
0 Kudos

Hi,Surai

I am trying your solution, but it failed to throw exception. I am checking the problem. thanks for your help further

former_member187339
Active Contributor
0 Kudos

Hi,

Can you tell in which test case the exception occured ? so that i can also try to solve it.

Regards

Suraj

Former Member
0 Kudos

Hi, Surai,

before add your mapping, my mapping is ok, after added your solution for gender element, it failed.

PS.

1.when I defined your udf function. for cache type, which one of "Queue", "Context","Value" do I choose?

2. the error message in message mapping testing.

"cxmlOrRFC" is my udf function.

14:41:58 Start of test

Exception:[java.lang.ArrayIndexOutOfBoundsException: 2] in class com.sap.xi.tf._MM_EN_CN_TO_MERGE_ method cxmlOrRFC$[, , com.sap.aii.mappingtool.flib3.CollapseContexts@b8511e, com.sap.aii.mappingtool.flib3.CollapseContexts@d58afd] com.sap.aii.utilxi.misc.api.BaseRuntimeException: Exception:[java.lang.ArrayIndexOutOfBoundsException: 2] in class com.sap.xi.tf._MM_EN_CN_TO_MERGE_ method cxmlOrRFC$[, , com.sap.aii.mappingtool.flib3.CollapseContexts@b8511e, com.sap.aii.mappingtool.flib3.CollapseContexts@d58afd] at com.sap.aii.mappingtool.tf3.rt.Q2QFunctionWrapper.cacheQueue(Q2QFunctionWrapper.java:105) at com.sap.aii.mappingtool.tf3.rt.Q2QFunctionWrapper.gotoNextContext(Q2QFunctionWrapper.java:43) at com.sap.aii.mappingtool.flib3.SplitByValue$SplitByEach.gotoNextContext(SplitByValue.java:127) at com.sap.aii.mappingtool.flib3.SplitByValue.gotoNextContext(SplitByValue.java:31) at com.sap.aii.mappingtool.tf3.AMappingProgram.processNode(AMappingProgram.java:144) at com.sap.aii.mappingtool.tf3.AMappingProgram.processNode(AMappingProgram.java:204) at com.sap.aii.mappingtool.tf3.AMappingProgram.processNode(AMappingProgram.java:204) at com.sap.aii.mappingtool.tf3.AMappingProgram.processNode(AMappingProgram.java:204) at com.sap.aii.mappingtool.tf3.AMappingProgram.processNode(AMappingProgram.java:204) at com.sap.aii.mappingtool.tf3.AMappingProgram.start(AMappingProgram.java:298) at com.sap.aii.mappingtool.tf3.Transformer.start(Transformer.java:63) at com.sap.aii.mappingtool.tf3.AMappingProgram.execute(AMappingProgram.java:77) at com.sap.aii.ibrep.server.mapping.ServerMapService.transformInternal(ServerMapService.java:431) at com.sap.aii.ibrep.server.mapping.ServerMapService.execute(ServerMapService.java:169) at com.sap.aii.ibrep.sbeans.mapping.MapServiceBean.execute(MapServiceBean.java:52) at com.sap.aii.ibrep.sbeans.mapping.MapServiceRemoteObjectImpl0.execute(MapServiceRemoteObjectImpl0.java:259) at com.sap.aii.ibrep.sbeans.mapping.MapServiceRemoteObjectImpl0p4_Skel.dispatch(MapServiceRemoteObjectImpl0p4_Skel.java:146) at com.sap.engine.services.rmi_p4.DispatchImpl._runInternal(DispatchImpl.java:294) at com.sap.engine.services.rmi_p4.DispatchImpl._run(DispatchImpl.java:183) at com.sap.engine.services.rmi_p4.server.P4SessionProcessor.request(P4SessionProcessor.java:119) at com.sap.engine.core.service630.context.cluster.session.ApplicationSessionMessageListener.process(ApplicationSessionMessageListener.java:33) at com.sap.engine.core.cluster.impl6.session.MessageRunner.run(MessageRunner.java:41) at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37) at java.security.AccessController.doPrivileged(Native Method) at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:95) at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:160) RuntimeException in Message-Mapping transformation: Exception:[java.lang.ArrayIndexOutOfBoundsException: 2] in class com.sap.xi.tf._MM_EN_CN_TO_MERGE_ method cxmlOrRFC$[, , com.sap.aii.mappingtool.flib3.CollapseContexts@b8511e, com.sap.aii.mappingtool.flib3.CollapseContexts@d58afd]

14:41:59 End of test

Message was edited by: Spring Tang

Message was edited by: Spring Tang

former_member187339
Active Contributor
0 Kudos

Hi,

Hope you have changed context as described in my previous reply and also you have used all the node functions.

>>when I defined your udf function. for cache type, which one of "Queue", "Context","Value" do I choose?

context...

>>the error message in message mapping testing.

looks like an array exception... can you give me the test instance which you are giving as the input?

Recheck the context of each node which is given as input...

Regards

Suraj

Former Member
0 Kudos

Hi Spring,

Thanks for trying out my suggestion.

If you are looking for a more convenient one, i.e. a user defined solution. You can try out what Suraj suggested. I did see ambiguity in his code which i would like to correct.

I have changed the code and the variable names so please pay attention to that

<b>Mapping: </b>

E_Students.Student.ID(context E_Students)----


|

C_Students.Student.ID(context C_Students)----


| createGender SplitbyValueGender

E_Students.Student.Gender(context Student)CollapseContext|

C_Students.Student.Sex (context Student)--CollapseContext|

Here createGender is a UDF:

<b>Note:</b> Method is by queue

public void createGender(String[] E_ID,String[] C_ID,String[] Gender,String[] Sex,ResultList result,Container container)

{

for (int k=0;k<E_ID.length;k++)

{

if (Gender[k].equals ("") )

{

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

if (E_ID[k].equals(C_ID[j]))

{

result.addValue(Sex[j]); break;

}

}

else

result.addValue(Gender[k]);

}

}

<b>TestData: </b>

<b>Input: </b>

<?xml version="1.0" encoding="UTF-8"?>

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">

<ns0:Message1>

<E_Students>

<Student>

<ID>1</ID>

<Name>A</Name>

<Gender>M</Gender>

</Student>

<Student>

<ID>3</ID>

<Name>B</Name>

</Student>

<Student>

<ID>2</ID>

<Name>C</Name>

</Student>

</E_Students>

</ns0:Message1>

<ns0:Message2>

<C_Students>

<Student>

<ID>2</ID>

<Name>C</Name>

<Sex>f</Sex>

</Student>

<Student>

<ID>1</ID>

<Name>A</Name>

<Sex>M</Sex>

</Student>

<Student>

<ID>3</ID>

<Name>B</Name>

<Sex>F</Sex>

</Student>

</C_Students>

</ns0:Message2>

</ns0:Messages>

<b>OutPut: </b>

<?xml version="1.0" encoding="UTF-8"?>

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">

<ns0:Message1>

<Students>

<Student>

<ID>1</ID>

<Name>A</Name>

<Gender>M</Gender>

</Student>

<Student>

<ID>3</ID>

<Name>B</Name>

<Gender>F</Gender>

</Student>

<Student>

<ID>2</ID>

<Name>C</Name>

<Gender>f</Gender>

</Student>

</Students>

</ns0:Message1>

</ns0:Messages>

Regards,

KNS Kumar.

Former Member
0 Kudos

mapping exception still reproduced.

I don't know clearly about the context. I just drag and drop the element from the xml tree to message mapping editor gui. do i need other steps for dealing with the context? I cannot understand your mapping rule E_Students.Student.Gender(context Student), why the context of E_Students.Student.Gender is Student, how to implement this?

Message was edited by: Spring Tang

Message was edited by: Spring Tang

Message was edited by: Spring Tang

former_member187339
Active Contributor
0 Kudos

Hi,

For changing the context right click on the node (eg: ID), you will see the context. In it choose the appropriate context as shown above.

And for the code, the code suggested by KNS failed with the following test data:

<E_Employees>

<Student>

<ID>1</ID>

<Name>a</Name>

<Sex>f</Sex>

</Student>

<Student>

<ID>4</ID>

<Name>d</Name>

</Student>

<Student>

<ID>3</ID>

<Name>c</Name>

<Sex>m</Sex>

</Student>

<Student>

<ID>2</ID>

<Name>b</Name>

</Student>

</E_Employees>

<C_Employees>

<Student>

<ID>3</ID>

<Name>c</Name>

</Student>

<Student>

<ID>4</ID>

<Name>d</Name>

<Gender>f</Gender>

</Student>

<Student>

<ID>2</ID>

<Name>b</Name>

<Gender>m</Gender>

</Student>

<Student>

<ID>1</ID>

<Name>a</Name>

</Student>

</C_Employees>

So what i suggest is that do an extesive test on the code and finalize one

Before that change context...

Regards

Suraj

Former Member
0 Kudos

Hi Spring,

If you rightclick on the corresponding element you will see the context and you can change it accordingly.

Dear Suraj,

The input structure given by the Spring as shown below

Source Structure1:

<?xml version="1.0" encoding="UTF-8"?>

<b><E_Students></b> Occurrence 1...1

|----<Student> Occurrence 1...Unbounded

|----


<ID> Occurrence 1...1

|----


<Name> Occurrence 1...1

|----


<b><Gender></b> Occurrence 1...1

Source Structure2:

<?xml version="1.0" encoding="UTF-8"?>

<b><C_Students></b> Occurrence 1...1

|----<Student> Occurrence 1...Unbounded

|----


<Index> Occurrence 1...1

|----


<Name> Occurrence 1...1

|----


<b><Sex></b> Occurrence 1...1

If you can see <b>Gender</b> comes under <b>E_Students</b> and <b>Sex</b> comes under <b>C_Students</b>,

Where as your structure as given below has <b>Sex</b> in <b>E_students</b>

<E_Employees>

<Student>

<ID>1</ID>

<Name>a</Name>

<Sex>f</Sex>

</Student>

Thus it is obvious that code will not work.

Please correct your structure then try…

Regards,

KNS Kumar.

Former Member
0 Kudos

Thanks Kumar & Surai, you two guys help me much on multiple mapping. I succeed with your help:)

Former Member
0 Kudos

Hi, Surai thank for your solution. further, thank Kumar for your correction:)

Former Member
0 Kudos

if the number of e_student and c_student is the same, then it is ok. if it is not, there is error. I will check. but i will appreciate it if you provide any fix:)

Former Member
0 Kudos

all is done, thanks:)

Answers (6)

Answers (6)

Former Member
0 Kudos

Hi,

E_Students.Student-->Students.Student

E_Students.ID>SORT>SplitByValue-->Students.ID

(Context of ID IS E_Students)

E_Students.ID------\

-


|SORT>SplitByValue>Students.Name

E_Students.Name--/

(Context of ID and Name IS E_Students)

Note: E_Students.ID is refered as ID1 and C_Students.ID as ID2

(Context of ID1 IS E_Students)

(Context of ID2 IS c_Students)

(Context of Gender IS Student)

(Context of Sex IS Student)

ID1----


\

-


|SortByKey>splitbyvalue\

Gender-->colapseContext-/

-


|stringequals>not>if

-


constanst("")-/

ID1----


\

-


|SortByKey>splitbyvalue\then

Gender-->colapseContext-/

ID2----


\

-


|SortByKey>splitbyvalue\else

sex-->colapseContext-/

Regards,

KNS Kumar.

Former Member
0 Kudos

Hi,Kumar.

Maybe your solution is right. but my xml schema is very large, I don't want to add sortbyKey at every mapping. I hope more convenient way. Thanks anyway:)

Message was edited by: Spring Tang

STALANKI
Active Contributor
0 Kudos

Hi Spring,

Have you tried the approach I have given and does it work?it z most simple way.

Former Member
0 Kudos

Hi, Sravya Talanki

there are no guranteed order between these two source xmls, I have some doubts for your suggestion.

Message was edited by: Spring Tang

Message was edited by: Spring Tang

Former Member
0 Kudos

1.I have no constants here, for "gender" element, it is my sample.

2. in one source xml structure, I used the gender, in the other source xml structure, I used sex. in these two source xml, maybe they are in no order.

Hope from your help in detail.

Former Member
0 Kudos

Hi Spring,

There is a graphical mapping function called constant which is there at the bottom along with the other standard functions like ifelse and the rest of them.so in that you can declare whatever value you want as constant.

when we use graphical mapping we will not have a problem as to the source message being gender in one and sex in the ther bcoz of the fact that, its going to check for only the condition you specify.

pls go thru this link to know more about the existing functions or standard functions:

http://help.sap.com/saphelp_nw04/helpdata/en/43/c4cdfc334824478090739c04c4a249/content.htm

or if u dont want to use the existing fucetions you can always write the user defined functions specified by others.

Regards,

abhy

Former Member
0 Kudos

Hi Spring,

The Steps to be done are as follows:

- Drag the field E_Students.student.Gender

- Select the standard function constant (and input a space as constant)

- select the not equals function.

- let the first 2 be the input to the not equals function.

- Drag the field C_Students.student.Sex

- then select the ifelse function

- let output from not equals and the C_Students.student.Sex be input for the ifesle function.

- let the out of the ifelse be Students.student.Gender

Now you will get the desired output.

Pls see this link which explains a similar scenario with a screen shot.

http://help.sap.com/saphelp_nw04/helpdata/en/5d/db0e83e8e74202a5bff527055ab7e5/content.htm

Regards,

abhy

Former Member
0 Kudos

Hi Spring,

check if e_student.studnt.gender<>constant without any value

then

map

e-student.student.gender-->students.student.gender

else

map

c-student.student.sex-->students.student.gender

other mappings r direct one to one mapping.

regards

jithesh

STALANKI
Active Contributor
0 Kudos

very easy.

write a small user defined function.

ud:mapgend

if (a!= null)

return a;

else

return b;

gender->a mapgend target field

sex->b

Former Member
0 Kudos

Hi Spring,

You can do it like this.During graphical mapping,

use a ifelse function which is predefined and there, your condition should be like this,

if E_Students.student.Gender <>(use notequal to function) a constant(specify space as ur constant) map it to Students.student.Gender else C_Students.student.Sex map this to Students.student.Gender

Regards,

abhy