cancel
Showing results for 
Search instead for 
Did you mean: 

Message split for nested tables

Former Member
0 Kudos

Hi all,

within PI 7.1 I want to split a message into multiple messages. But unfortunately using functions "UseOneAsMany" or "Concat" alone do not help me at all.

I think I need to combine this some how...

My source message has simplified following structure (including cardinality in brackets):

<OrderIn (1..1)>
  <OrderData (1..n)>
    <OrderDetails (1..1)>
      <OrderNumber (1..1)></OrderNumber>
      <Customer (1..1)></Customer>
    </OrderDetails>
    <DistirbutionRules (1..n)>
      <Rule (1..1)></Rule>
      <Description (1..1)></Description>
    </DistirbutionRules>
  </OrderData>
  <TargetSystem (1..1)>
    <SystemID (1..n)></SystemID>
  </TargetSystem>
</OrderIn>

My target message has simplified following structure (including cardinality in brackets):

<OrderOut (1..n)>
  <OrderData (1..n)>
    <TargetSystem (1..1)></TargetSystem>
    <OrderDetails (1..1)>
      <OrderNumber (1..1)></OrderNumber>
      <Customer (1..1)></Customer>
    </OrderDetails>
    <DistirbutionRules (1..n)>
      <Rule (1..1)></Rule>
      <Description (1..1)></Description>
    </DistirbutionRules>
  </OrderData>
</OrderOut>

So as incomming message I can have multiple orders and multiple target systems.

As result of the mapping I need one message per target system including all orders in the message.

As long as I have only one Order (OrderData) within the message and only one DistributionRule I can work with function UseOneAsMany as described.

But as soon as more than one Order or DistributionRule is defined I get a conversion error "Too many values in the first queue in function useOneAsMany".

Here the UseOneAsMany mapping (as Text Preview):

/ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderOut/OrderData=SplitByValue(useOneAsMany(/ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn/OrderData, /ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn/TargetSystem/SystemID, /ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn/TargetSystem/SystemID, result), type=0)

When I use only the Concat function I get no error even if I have multiple OrderData but only the first OrderData or DistributionRule is mapped to the target structure.

Here the Concat mapping (as Text Preview):

/ns0:Messages/ns0:Message1/ns1:OrderOut/OrderData=SplitByValue(concat(/ns0:Messages/ns0:Message1/ns1:OrderIn/OrderData, ifWithoutElse(exists(/ns0:Messages/ns0:Message1/ns1:OrderIn/TargetSystem/SystemID), const(value=), keepss=false), delimeter=), type=0)

regards

René

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Rene

use the patterns defined in the component SAP BASIS 6.40

regards

sandeep

Former Member
0 Kudos

Hi Rene,

I think xslt or java mapping would be easier aproach for this.

However if you want to use message mapping here is the solution.

We need to map following:

Order_out - Use OneAsMany as discussed earlier.

OrderData -

Write UDF with 2 parameters of type Context:

for(int i =0; i < Integer.parseInt(b[0]); i++)

{

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

result.addValue(a[j]);

result.addValue(ResultList.CC);

}

Here a - OrderData

b - Count of SystemIds

Repeat all the OrderData nodes for the no. of times of SystemIds and add context change for each repeatition.

OrderDetail, DistributionRules -

Write UDF with 2 parameters of type queue:

Code will same as above but challenge here is to generate context change.

There are 2 level of context change (OrderIn and OrderData) so we need to use queue so repeat the queue twice and add context change for each repeatition.

here a - OrderDetail

b - Count of SystemIds

OrderNumber, Customer -

Use the same UDF as OrderData but here a = (removeContext)OrderNumber

b - Count of SystemIds

apply splitbyvalue before mapping to target field

Target System -

Here we need to repeat SystemId and apply split by value before mapping to target node.

Use this UDF

for (int j = 0; j < Integer.parseInt(b[0]); j++)

{result.addValue(a[j]);

result.addValue(a[j]);}

here,

a - SystemId

b - Count of SystemIds

Hope this will help.

However UDF for OrderDetails and DistributionRules is using queue which is not efficient for performance.

So please check your system resources and performance before using it.

Thanks,

Beena.

Edited by: Beena Thekdi on Dec 15, 2008 12:05 PM

Answers (5)

Answers (5)

Former Member
0 Kudos

Hi Damian,

have a look at the hierarchy. Within the Source Structure "TargetSystem" and "OrderData" are independent from each other. To get the target messages I want to copy the whole "OrderData" table as many times as I have target systems. Like:

<OrderIn>
  <OrderData>
    <OrderDetails>
      <OrderNumber>1</OrderNumber>
      <Customer>Cust1</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule1</Rule>
      <Description>Desc1</Description>
    </DistirbutionRules>
  </OrderData>
  <OrderData>
    <OrderDetails>
      <OrderNumber>2</OrderNumber>
      <Customer>Cust2</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule2</Rule>
      <Description>Desc2</Description>
    </DistirbutionRules>
  </OrderData>
  <TargetSystem>
    <SystemID>A</SystemID>
    <SystemID>B</SystemID>
  </TargetSystem>
</OrderIn>

After mapping and splitting I want to get:

<OrderOut>
  <OrderData>
    <TargetSystem>A</TargetSystem>
    <OrderDetails>
      <OrderNumber>1</OrderNumber>
      <Customer>Cust1</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule1</Rule>
      <Description>Desc1</Description>
    </DistirbutionRules>
  </OrderData>
  <OrderData>
    <TargetSystem>A</TargetSystem>
    <OrderDetails>
      <OrderNumber>2</OrderNumber>
      <Customer>Cust2</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule2</Rule>
      <Description>Desc2</Description>
    </DistirbutionRules>
  </OrderData>
</OrderOut>
<OrderOut>
  <OrderData>
    <TargetSystem>B</TargetSystem>
    <OrderDetails>
      <OrderNumber>1</OrderNumber>
      <Customer>Cust1</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule1</Rule>
      <Description>Desc1</Description>
    </DistirbutionRules>
  </OrderData>
  <OrderData>
    <TargetSystem>B</TargetSystem>
    <OrderDetails>
      <OrderNumber>2</OrderNumber>
      <Customer>Cust2</Customer>
    </OrderDetails>
    <DistirbutionRules>
      <Rule>Rule2</Rule>
      <Description>Desc2</Description>
    </DistirbutionRules>
  </OrderData>
</OrderOut>

regards

René

Former Member
0 Kudos

You say

"So as incomming message I can have multiple orders and multiple target systems"

From the input structure how is it possible to associate a Target system to an Order ? they are at the same level in the input structure. Is it the case of something like ?

<OrderData>

<OrderDetails>

<OrderNumber>1</OrderNumber>

</OrderDetails>

</OrderData>

<OrderData>

<OrderDetails>

<OrderNumber>2</OrderNumber>

</OrderDetails>

</OrderData>

<TargetSystem>

<SystemID>123</SystemID>

</TargetSystem>

........

<OrderData>

<OrderDetails>

<OrderNumber>10</OrderNumber>

</OrderDetails>

</OrderData>

<OrderData>

<OrderDetails>

<OrderNumber>11</OrderNumber>

</OrderDetails>

</OrderData>

<TargetSystem>

<SystemID>456</SystemID>

</TargetSystem>

Thanks

Damien

Former Member
0 Kudos

Hi all,

as my problem is still not answered - can someone help me on this?

regards

René

Former Member
0 Kudos

Hi Beena,

The OrderOut structure is already created in the correct quantity of target SystemIDs. So for every SystemID I already get one OrderOut message

What is not working is, that all OrderData and DistributionRules are mapped.

Using Concat only the first OrderData is mapped. So every OrderOut message only contains of the first OrderData. The rest seems simply to be ignored.

For UseOneAsMany I get an error as sonn as I have more than one OrderData.

regards

René

Former Member
0 Kudos

Hi,

As result of the mapping I need one message per target system including all orders in the message.

I think you can try this:

Use OrderIn as first queue, and ids as second and third queue and map to OrderOut.

This will repeat all orders in OrderIn per target system and create one OrderOut node per target system including all orders.

/ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderOut=SplitByValue(useOneAsMany(/ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn, /ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn/TargetSystem/SystemID, /ns0:Messages/ns0:Message1/ns1:RJ_SalesOrderIn/TargetSystem/SystemID, result), type=0)

Thanks,

Beena.