Author |
Message
|
GARNOLD5551212 |
Posted: Thu Oct 17, 2013 7:24 am Post subject: Mapping Node How can I Create multiple segments from one |
|
|
Novice
Joined: 23 Jul 2013 Posts: 13
|
I have a system that requires us to break out a line item of quantities greater than one into individual line items with a quantity of one. The map is semi complex and now I need to add this functionality.
It is simple to filter to a sub map when a line item is > 1, but how can I use the qty as an index to create say 3 (qty=3) output segments?
I've left the first mapping alone, and wanted to run it through a second map to just break out the order line segments based on qty. I thought of trying to map to a local env schema to create my index, but that has the same problem how do I turn qty n+1 into n+1 segments?
We are trying to stay Primarily Map Nodes and secondly Java Compute nodes within our deployment, but have only added some basic Java Compute nodes to date, no full maps or significant development in Java Compute nodes to date. Only simple data conversions not handled in Map nodes extended in Java.
Toolkit Version:
Build id: 8.0.0.2-IFix-20130709-1003 |
|
Back to top |
|
 |
kimbert |
Posted: Thu Oct 17, 2013 7:33 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
|
Back to top |
|
 |
GARNOLD5551212 |
Posted: Thu Oct 17, 2013 8:19 am Post subject: |
|
|
Novice
Joined: 23 Jul 2013 Posts: 13
|
The forEach doesn't work because the input is not an array. I'm looking for a way to do a for (int tmpi=0;tmpi<Qty;tmpi++) and produce 3 outputs.
example input:
<Line>
<Item value='Book'/>
<Qty value=3/>
</Line>
Desired output:
<Line>
<Item value='Book'/>
<Qty value=1/>
</Line>
<Line>
<Item value='Book'/>
<Qty value=1/>
</Line>
<Line>
<Item value='Book'/>
<Qty value=1/>
</Line> |
|
Back to top |
|
 |
Vitor |
Posted: Thu Oct 17, 2013 8:46 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
As indicated in your previous thread here, it's sometimes better to write a few lines of ESQL or Java than tie yourself in knots with a Mapping node trying to avoid it.
Perhaps (and someone who knows more than me will hopefully comment) you could produce a custom Java function and call it from the map.
Don't use a hammer to put a screw in just because you have a lot of nails of different sizes and an extensive range of hammers. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
GARNOLD5551212 |
Posted: Thu Oct 17, 2013 10:16 am Post subject: |
|
|
Novice
Joined: 23 Jul 2013 Posts: 13
|
Thanks for the thoughts. I just didn't want to miss something simple.
I'll go through the Java Compute Examples and see if I can find one that points me in the right direction. Just haven't done mapping from a compute node yet, time to learn something new.
I don't think it can be a Custom Java Transform within the Map Node because that would just drop the xml into the element I was moving the data to. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Oct 17, 2013 10:33 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
GARNOLD5551212 wrote: |
I'll go through the Java Compute Examples and see if I can find one that points me in the right direction. Just haven't done mapping from a compute node yet, time to learn something new. |
Well in ESQL it's something like:
Code: |
SET iTemp = InputRoot.XMLNSC.Line.Qty.value;
MOVE rIn TO InputRoot.XMLNSC.Line;
WHILE iTemp > 0 DO
CREATE LASTCHILD OF OutputRoot.XMLNSC AS rOut FROM rIn;
SET rOut.value = 1;
SET iTemp = iTemp -1;
END DO;
|
(This code is untested, may not compile and may not represent the best solution to the problem described. No liability, express or implied, is accepted for loss or damage resulting from it's use or even just reading it)
GARNOLD5551212 wrote: |
I don't think it can be a Custom Java Transform within the Map Node because that would just drop the xml into the element I was moving the data to. |
I'll take your word on Java. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Oct 17, 2013 10:41 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
You can do it in mapping node.
You connect the foreach transform to the output message.
This will create one output message for each input section. |
|
Back to top |
|
 |
gs |
Posted: Thu Oct 17, 2013 10:49 am Post subject: |
|
|
 Master
Joined: 31 May 2007 Posts: 254 Location: Sweden
|
mqjeff wrote: |
You can do it in mapping node.
You connect the foreach transform to the output message.
This will create one output message for each input section. |
My understanding of his XML example was that he wanted the output in one single message. Also, the for each statement only works on element occurrences not its integer value? |
|
Back to top |
|
 |
gs |
Posted: Thu Oct 17, 2013 10:51 am Post subject: |
|
|
 Master
Joined: 31 May 2007 Posts: 254 Location: Sweden
|
Vitor wrote: |
GARNOLD5551212 wrote: |
I don't think it can be a Custom Java Transform within the Map Node because that would just drop the xml into the element I was moving the data to. |
I'll take your word on Java. |
Also IMO pure java mapping may in some cases be better from a code maintainability perspective. Easier to follow documentable java code than complex mappings with custom java classes.
Last edited by gs on Thu Oct 17, 2013 11:15 am; edited 1 time in total |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Oct 17, 2013 11:04 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
gs wrote: |
mqjeff wrote: |
You can do it in mapping node.
You connect the foreach transform to the output message.
This will create one output message for each input section. |
My understanding of his XML example was that he wanted the output in one single message. Also, the for each statement only works on element occurrences not its integer value? |
There's documentation on mapping a single element to multiple outputs.
 |
|
Back to top |
|
 |
gs |
Posted: Thu Oct 17, 2013 11:17 am Post subject: |
|
|
 Master
Joined: 31 May 2007 Posts: 254 Location: Sweden
|
mqjeff wrote: |
gs wrote: |
mqjeff wrote: |
You can do it in mapping node.
You connect the foreach transform to the output message.
This will create one output message for each input section. |
My understanding of his XML example was that he wanted the output in one single message. Also, the for each statement only works on element occurrences not its integer value? |
There's documentation on mapping a single element to multiple outputs.
 |
I don't disagree with you. I'm just stating that it doesn't sound like what he wants to do. |
|
Back to top |
|
 |
GARNOLD5551212 |
Posted: Thu Oct 17, 2013 11:40 am Post subject: |
|
|
Novice
Joined: 23 Jul 2013 Posts: 13
|
gs wrote: |
mqjeff wrote: |
gs wrote: |
mqjeff wrote: |
You can do it in mapping node.
You connect the foreach transform to the output message.
This will create one output message for each input section. |
My understanding of his XML example was that he wanted the output in one single message. Also, the for each statement only works on element occurrences not its integer value? |
There's documentation on mapping a single element to multiple outputs.
 |
I don't disagree with you. I'm just stating that it doesn't sound like what he wants to do. |
GS,
You are correct, based on the integer value of Qty, I want to create n+1 output segments [1..*] of <Line> only changing the Qty=1 for each instance of the document segment.
So in the Compute node I'll need to copy up to the segment matching my condition (fn:starts-with($Order/OrderLines/OrderLine/Item/@ItemID, 'GFT') and $OrderedQty>1) and create duplicate OrderLines as Vitor shows, then copy the rest of the document to the output. |
|
Back to top |
|
 |
gs |
Posted: Thu Oct 17, 2013 11:47 am Post subject: |
|
|
 Master
Joined: 31 May 2007 Posts: 254 Location: Sweden
|
GARNOLD5551212 wrote: |
GS,
You are correct, based on the integer value of Qty, I want to create n+1 output segments [1..*] of <Line> only changing the Qty=1 for each instance of the document segment.
So in the Compute node I'll need to copy up to the segment matching my condition (fn:starts-with($Order/OrderLines/OrderLine/Item/@ItemID, 'GFT') and $OrderedQty>1) and create duplicate OrderLines as Vitor shows, then copy the rest of the document to the output. |
Why not do it in a Java Compute node if that's your secondary choice of node? |
|
Back to top |
|
 |
GARNOLD5551212 |
Posted: Thu Oct 17, 2013 12:24 pm Post subject: |
|
|
Novice
Joined: 23 Jul 2013 Posts: 13
|
gs wrote: |
GARNOLD5551212 wrote: |
GS,
You are correct, based on the integer value of Qty, I want to create n+1 output segments [1..*] of <Line> only changing the Qty=1 for each instance of the document segment.
So in the Compute node I'll need to copy up to the segment matching my condition (fn:starts-with($Order/OrderLines/OrderLine/Item/@ItemID, 'GFT') and $OrderedQty>1) and create duplicate OrderLines as Vitor shows, then copy the rest of the document to the output. |
Why not do it in a Java Compute node if that's your secondary choice of node? |
Yes I'll do it in Java Compute since that's my background and I don't know ESQL. I just meant that Vitor's pseudo code was the concept I needed to follow. Thanks for your input. |
|
Back to top |
|
 |
martinb |
Posted: Sat Oct 19, 2013 12:28 am Post subject: |
|
|
Master
Joined: 09 Nov 2006 Posts: 210 Location: UK
|
To implement this in the Mapping node I would consider using the "Append" transform:
Append
The Append transform produces occurrences of an output array in the order of the inputs.
The Append transform takes multiple inputs of either simple type or complex type. The output must be an array of either a simple type or a complex type.
....
In this case you could take multiple connections from the singleton input "Line" type to append the required instances of the target repeating "Line", using a condition based on "Qty value" in your input "Line" to determine how many would be output. |
|
Back to top |
|
 |
|