cancel
Showing results for 
Search instead for 
Did you mean: 

XI Mapping Question

Former Member
0 Kudos

I have a simple XML structure as follows:

<A>

<row><item>1</item></row>

<row><item>1</item></row>

<row><item>2</item></row>

</A>

I need to consolidate all the <row> records into <group> records

whenever <item> changes, for example:

<A>

<group>

<row><item>1</item></row>

<row><item>1</item></row>

</group>

<group>

<row><item>2</item></row>

</group>

</A>

I've tried the SplitByValue(), collapseContents() removeContents() node

functions but cannot come up with a workable solution. Can anyone provide a suggestion?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Suresh,

It sounds like you are on the right track but it still did not give desired results.

<A>

<row><item>1</item></row>

<row><item>2</item></row>

</A>

produced:

<A>

<row><item>1</item></row>

</A>

It completely skipped the second row. Do you have any suggestion to fine tune this?

Brian

Former Member
0 Kudos

Brian,

I tried with your input and got:

<A>

<group>

<row>

<item>1</item>

</row>

</group>

<group>

<row>

<item>2</item>

</row>

</group>

</A>

which was what you wanted?

The text preview in the message mapping editor shows this:

/A=/A

/A/group=nodeChangeList([]SplitByValue([type=Value changed]/<b>A</b>/row/item))

/A/group/row=SplitByValue([type=Value changed]/<b>A</b>/row/item)

/A/group/row/item=/A/row/item

Regards,

Suresh

Former Member
0 Kudos

Did you use SplitByValue in your mapping, or did you completly remove that requirement?

Former Member
0 Kudos

I used splitByValue with valuechanged for both item->group and item-> row mappings.

<A> --> <A>

<item (ctx = A)> ->SplitByValue(Value Changed)-> contextChangeList -> <group>

<item (ctx = A)> ->SplitByValue(Value Changed)-> <row>

<item> -> <item>

Former Member
0 Kudos

It will be helpful if you could post the mapping content of the text preview of your mapping.

Former Member
0 Kudos

Suresh,

Can you post the source of the nodeChangeList() function that you have defined below? You offered several code snippets above so I want to make sure that I'm using the version that you tested.

/A=/A

/A/group=nodeChangeList([]SplitByValue([type=Value changed]/A/row/item))

/A/group/row=SplitByValue([type=Value changed]/A/row/item)

/A/group/row/item=/A/row/item

Brian

Former Member
0 Kudos

Brian,

Here you go:

if(a.length > 0) {
  result.addValue("newgroup");
}
for(int i=0;i<a.length; i++){
  if(a<i>.equals(ResultList.CC)){
     result.addValue("newgroup");
  }
}

Make sure you check the 'Cache Entire Queue' checkbox in the user-defined function. (the function is an advanced user-defined function and has 1 argument)

Also while mapping item -> group and item -> row, the context of item is 'A' and not 'row'.

Regards,

Suresh.

Answers (5)

Answers (5)

Former Member
0 Kudos

Try the following

1. Map the item to Group and change the context of item to A (root node)Write an Advanced function for creating the required no of Groups

//write your code here

result.addValue("0");

for(int i=0;i<a.length-1;i++)

{

if(!a<i>.equals(a[i+1])){

result.addValue(a<i>);

}

}

2. Map the item to row and change the context of item to A (root node,)Write another function for creating required no of rows in each group

//write your code here

result.addValue(a[0]);

for(int i=0;i<a.length-1;i++)

{

if (!a<i>.equals(a[i+1]))

result.addContextChange();

result.addValue(a[i+1]);

}

3. Map Item to Item, leave the context as it is.

This should solve your problem.

Thanks

Abinash

Former Member
0 Kudos

J.R. & Joachim,

Thanks for the input. Both soutions using SplitByValue produced similar results, but the grouping was not performed. I received the following output:

<A>

<group><row><item>1</item></row>

<group><row><item>1</item></row>

<group><row><item>2</item></row>

</A>

This was the same approach I tried yesterday but could never achieve the desired results. I was close when I tried:

<A> --> <A>

<item (ctx = A)> ->SplitByValue(Value Changed)-> <group>

<item (ctx = A)> ->SplitByValue(Value Changed)-> <row>

<item> -> <item>

But this failed when I added a 4th input row.

Former Member
0 Kudos

Brian,

Your approach does not produce desired results because when you do a splitbyvalue on item and map it to group, the number of groups will be equal to the number of items with '1' (the first value) and not the number of context changes.

In order to do what you want, one of the options is to create an advanced user-defined function 'contextChangeList' with 1 argument (enter argument count as 1 while creating the function) like:

if(a.length > 0) {
  result.addValue("newgroup");
}
for(int i=0;i<a.length; i++){
  if(a<i>.equals(ResultList.CC)){
     result.addValue("newgroup");
  }
}

As a result, your mapping will look like

<A> --> <A>
<item (ctx = A)> ->SplitByValue(Value Changed)-> contextChangeList -> <group>
<item (ctx = A)> ->SplitByValue(Value Changed)-> <row>
<item> -> <item>

Let me know if that works.

Regards,

Suresh.

Former Member
0 Kudos

Brian,

Your approach does not produce desired results because

when you do a splitbyvalue on item and map it to group,

the number of groups will be equal to the number of

items with '1' (the first value) and not the number of

context changes.

In order to do what you want, one of the options

is to create an advanced user-defined function 'contextChangeList' with 1 argument

(enter argument count as 1 while creating the function) like:


if(a.length > 0) {
  result.addValue("newgroup");
}
for(int i=0;i<a.length; i++){
  if(a.equals(ResultList.CC)){
     result.addValue("newgroup");
  }
}

As a result, your mapping will look like

<A> --> <A>

<item (ctx = A)> ->SplitByValue(Value Changed)-> contextChangeList -> <group>

<item (ctx = A)> ->SplitByValue(Value Changed)-> <row>

<item> -> <item>

Let me know if that works.

Regards,

Suresh.

Former Member
0 Kudos

Hi Brian,

I'd follow Suraj suggestions, with slide modifications:

<A> ---> <A>

<row> -> splitbyvalue(<b>value changed</b>) -> <b>collapseContexts</b> -> <group>

<row> ---> splitbyvalue(<b>value changed</b>) -


> <row>

<item> ---> <item>

Best regards

Joachim

Former Member
0 Kudos

Hi Brian

In case you want to do the same using XSLT, you can check my code sample, which speaks of how to handle ur requirement.

https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/xi/xi-code-samples... xslt mapping in sap xi, part i.pdf

cheers

Sameer

former_member187339
Active Contributor
0 Kudos

Hi Brian,

Try this

<A> ---> <A>

<row> ---> <group>

<row> ---> splitbyvalue -


> <row>

<item> ---> <item>

Hope this will be helpful.

Regards

Suraj