cancel
Showing results for 
Search instead for 
Did you mean: 

Mapping Idoc to Flat file

Former Member
0 Kudos

Hi,

I hv a situation where the idoc have to be mapped to a flat file:

Idoc(nested structure)

-


Delivery(0..N)

Item(0..N)

Batch(0..N)

Target (Flat File -all nodes at same level)

-


Delivery(0..N)

Item(0..N)

Batch(0..N)

Required structure sample

-


Delivery1

Item1

Batch1

Batch2

Item2

Batch1

Batch2

Delivery2

Item1

Batch1

Item2

Batch1

Batch2

I did a 1:N multi mapping in the graphical mapping and mapped Delivery node(Idoc) to Delivery Node(Flat file), and Item node (Idoc) to Delivery node(Flat File) - no context change. Then mapped Batch(Idoc) to Batch(Flat File) - context same as Delivery.

The problem is, the mapping produces Delivery nodes ok, BUT produces only ONE item Node and the batches of one item only. Rest of the items are suppressed. I tried context change, remove context, collapse context, etc.

I understand the context change should be linked with a user function. Do you guys have any suggestion..

I understand there is a queue for each hierarchy level, does it mean, in this case, the queue will contain, one item and ALL its batches, next queue will contain second item and all its batches and so on.

Or, will the queue contain just the items, and batches separtely.

Any suggestions will be helpful...

Thanks

Pandari

Accepted Solutions (0)

Answers (4)

Answers (4)

Former Member
0 Kudos

Hi!

This is realy easy to do with xsl. Attached is the xsl-code. Maybe it's help you.

Leo

-


<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet extension-element-prefixes="" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output encoding="ISO-8859-1" indent="yes" method="xml"/>

<xsl:template match="/">

<xsl:for-each select="/*">

<TRoot>

<IDOC>

<xsl:for-each select="IDOC/Del">

<xsl:element name="tnode">

<xsl:value-of select="DelNr"/>

</xsl:element>

<xsl:for-each select="Item">

<xsl:element name="tnode">

<xsl:value-of select="ItemNr"/>

</xsl:element>

<xsl:for-each select="Batch">

<xsl:element name="tnode">

<xsl:value-of select="BatchNr"/>

</xsl:element>

</xsl:for-each>

</xsl:for-each>

</xsl:for-each>

</IDOC>

</TRoot>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

Former Member
0 Kudos

Thanks for your suggestion. But, my requirement is different from yours. In your case you have Delivery, ALL items, ALL Batches. Whereas, in my case, it is Delivery, ITEM1, IT's batches, ITEM2, it's batches, etc.

I need to separate the item and it's batches. your's is consolidation. (I could get the consolidation without problem, the issues is separation)

Any other thoughts..

thx

former_member184154
Active Contributor
0 Kudos

<b>But you'll never gonna get there with graphical mapping!</b>

Either you use an extra XSL/Java/ABAP mapping to do a sort afterwards (but in any case you must have a field linking del-items-batches) or you use only an XSL/Java/ABAP mapping: there you can append nodes in the order you prefer.

Hope it's clear.

Alex

Former Member
0 Kudos

Hi Please see the code below, hope this comes in handy

<b>Source structure:</b>

<root>(1:1)

<IDOC>(1:1)

<Del>(0:unbounded)

<DelNr>(1:1)

<Item>(0:unbounded)

<ItemNr>(1:1)

<Batch>(0:unbounded)

<BatchNr>(1:1)

<b>TragetStructure:</b>

<root>(1:1)

<IDOC>(1:1)

<tnode>(0:unbounded)

<b>Input TestData:</b>

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

<root>

<IDOC>

<Del>

<DelNr>del1</DelNr>

<Item>

<ItemNr>it1-1</ItemNr>

<Batch>

<BatchNr>b1-1-1</BatchNr>

</Batch>

</Item>

<Item>

<ItemNr>it1-2</ItemNr>

<Batch>

<BatchNr>b1-2-1</BatchNr>

</Batch>

<Batch>

<BatchNr>b1-2-2</BatchNr>

</Batch>

</Item>

</Del>

<Del>

<DelNr>del2</DelNr>

<Item>

<ItemNr>it2-1</ItemNr>

<Batch>

<BatchNr>b2-1-1</BatchNr>

</Batch>

<Batch>

<BatchNr>b2-1-2</BatchNr>

</Batch>

</Item>

<Item>

<ItemNr>it2-2</ItemNr>

<Batch>

<BatchNr>b2-2-1</BatchNr>

</Batch>

</Item>

</Del>

</IDOC>

</root>

<b>OutPut Data:</b>

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

<TRoot>

<IDOC>

<tnode>del1</tnode>

<tnode>it1-1</tnode>

<tnode>b1-1-1</tnode>

<tnode>it1-2</tnode>

<tnode>b1-2-1</tnode>

<tnode>b1-2-2</tnode>

<tnode>del2</tnode>

<tnode>it2-1</tnode>

<tnode>b2-1-1</tnode>

<tnode>b2-1-2</tnode>

<tnode>it2-2</tnode>

<tnode>b2-2-1</tnode>

</IDOC>

</TRoot>

<b>Mapping:</b>

<root> --><TRoot>

<IDOC> --><IDOC>

DelNr (context is Del)----


|

-


|group|RemoveContexts|tnode

-


|

ItemNr (context is Del)|----


|

-


|

-


|--changeContext--|

-


|

ItemNr (context is item)--|

-


|-group-|

BatchNr(context is item)-|

<b>TextPreview(of mapping):</b>

/TRoot=/root=

/TRoot/IDOC=/root/IDOC=

/TRoot/IDOC/tnode=removeContexts(group(/root/IDOC/Del/DelNr=, changeContext(/root/IDOC/Del/Item/ItemNr=, group(/root/IDOC/Del/Item/ItemNr=, /root/IDOC/Del/Item/Batch/BatchNr=))))

<b>UserDefined Functions:</b>

<u><b>Note:</b></u> While defining this function choose the radio button Context (instead of value or queue)

public void group(String[] input1,String[] input2,ResultList result,Container container){

result.addValue(input1[0]);

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

result.addValue(input2<i>);

}

<u><b>Note:</b></u> While defining this function choose the radio button queue (instead of value or context)

public void changeContext(String[] input1,String[] input2,ResultList result,Container container){

//write your code here

String ContextChange="__cC_";

int LastContexj=0;

for(int i=0,j=0,ExternalCounter=0;i<input1.length;i++)

{

if(input1<i>.equals(ContextChange))

{

for(int InternalCounter=0;j<input2.length&&InternalCounter!=ExternalCounter;j++)

{

if(!input2[j].equals(ContextChange))

{

result.addValue(input2[j]);

}

else

{

InternalCounter++;

}

}

ExternalCounter=0;

result.addValue(result.CC);LastContexj=j;

}

else

{

ExternalCounter++;

}

}

for(int j=LastContexj;j<input2.length;j++)

if(!input2[j].equals(ContextChange))

result.addValue(input2[j]);

}

Regards,

KNS Kumar.

Former Member
0 Kudos

hi,

thanks for your comments. i already looked at this, looked again. didn't help much. there is no link between the delivery and the batches, except batches are within the delivery node. any other thoughts??

thx

former_member184154
Active Contributor
0 Kudos

Hi,

I've realized something on my system that should resemble your case, and I had no problem.

This is my input:


<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <ns1:DeliveryNested xmlns:ns1="http://guarneri.it/AeonvisLab">
         <Del>
            <DelNr>del1</DelNr>
            <Item>
               <ItemNr>it1-1</ItemNr>
               <Batch>
                  <BatchNr>b1-1-1</BatchNr>
               </Batch>
            </Item>
            <Item>
               <ItemNr>it1-2</ItemNr>
               <Batch>
                  <BatchNr>b1-2-1</BatchNr>
               </Batch>
               <Batch>
                  <BatchNr>b1-2-2</BatchNr>
               </Batch>
            </Item>
         </Del>
         <Del>
            <DelNr>del2</DelNr>
            <Item>
               <ItemNr>it2-1</ItemNr>
               <Batch>
                  <BatchNr>b2-1-1</BatchNr>
               </Batch>
               <Batch>
                  <BatchNr>b2-1-2</BatchNr>
               </Batch>
            </Item>
            <Item>
               <ItemNr>it2-2</ItemNr>
               <Batch>
                  <BatchNr>b2-2-1</BatchNr>
               </Batch>
            </Item>
         </Del>
      </ns1:DeliveryNested>
   </ns0:Message1>
</ns0:Messages>

And this is the output:


<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <ns1:DeliveryFlat xmlns:ns1="http://guarneri.it/AeonvisLab">
         <Del>
            <DelNr>del1</DelNr>
         </Del>
         <Item>
            <ItemNr>it1-1</ItemNr>
         </Item>
         <Item>
            <ItemNr>it1-2</ItemNr>
         </Item>
         <Batch>
            <BatchNr>b1-1-1</BatchNr>
         </Batch>
         <Batch>
            <BatchNr>b1-2-1</BatchNr>
         </Batch>
         <Batch>
            <BatchNr>b1-2-2</BatchNr>
         </Batch>
      </ns1:DeliveryFlat>
      <ns1:DeliveryFlat xmlns:ns1="http://guarneri.it/AeonvisLab">
         <Del>
            <DelNr>del2</DelNr>
         </Del>
         <Item>
            <ItemNr>it2-1</ItemNr>
         </Item>
         <Item>
            <ItemNr>it2-2</ItemNr>
         </Item>
         <Batch>
            <BatchNr>b2-1-1</BatchNr>
         </Batch>
         <Batch>
            <BatchNr>b2-1-2</BatchNr>
         </Batch>
         <Batch>
            <BatchNr>b2-2-1</BatchNr>
         </Batch>
      </ns1:DeliveryFlat>
   </ns0:Message1>
</ns0:Messages>

The best snapshot I could made on the mapping is here:

http://alegua.freeserverhost.com/tmp/mappingNested2Flat.jpg

Every source node is at its std ctx except Batch, for which I put ctx at Del level.

Let me know.

Alex

former_member184154
Active Contributor
0 Kudos

I always mess up a bit with this kind of mappings, but usually always get what I want

Anyway, a deep look at the example message mappings in the help.sap.com could really aid.

http://help.sap.com/saphelp_nw04/helpdata/en/ec/8fb142d043b911e10000000a1550b0/content.htm

Also, I would map the Idoc delivery with your message root element, and the target delivery node with an empty constant. When mapping items and batches do use a SplitByValue (each value).