cancel
Showing results for 
Search instead for 
Did you mean: 

XSLT mapping query

anilekar
Participant
0 Kudos

Hi All

I have done a XSLT mapping to map a flat file structure to a hierarchical structure. But my 3rd level node is getting repeated for 2nd level node. Please find the details below

Source Structure - flat file

Header - 1

Record - 1....unbound

Forecast - 1....unbound

Target Structure

level1 - MessageHeader - 1

level1 - ProductActivity - 1

level 2 Record - 1...unbound

level 3 Forecast - 1...unbound

*Sample Format of Source file*

Header

Record1

Forecast1.1

Forecast1.2

Record2

Forecast 2.1

Forecast 2.2

Now after execution of XSLT mapping the output I am getting contains all Forecast nodes for every record. For example output of above mentioned format is

*Sample Format of target structure*

MessageHeader

ProductActivity

Record1

Forecast1.1

Forecast1.2

Forecast2.1

Forecast2.2

Record2

Forecast1.1

Forecast1.2

Forecast2.1

Forecast2.2

Expected Output

MessageHeader

ProductActivity

Record1

Forecast1.1

Forecast1.2

Record2

Forecast2.1

Forecast2.2

Here is code for forcast row

<!-- TimeSeries: Net demand forecast(Dynamic replenishment) and Planned Receipt (SNI)-->
<xsl:if test="$ProcessFlag= 'SM'">
<OrderForecastTimeSeries>
<xsl:for-each select="//Forecast">
<Item>
<ValidityPeriod>
<StartDateTime><xsl:value-of select="substring(./ForecastDate, 1,4)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring(./ForecastDate,5,2)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring(./ForecastDate,7,2)"/>
<xsl:text>T</xsl:text>
<xsl:text>00:00:00</xsl:text>
</StartDateTime>
<EndDateTime>
<xsl:value-of select="substring(./ForecastDate, 1,4)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring(./ForecastDate,5,2)"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="substring(./ForecastDate,7,2)"/>
<xsl:text>T</xsl:text>
<xsl:text>00:00:00</xsl:text>
</EndDateTime>
</ValidityPeriod>
<Quantity>
<xsl:attribute name="unitCode"><xsl:value-of select="Unit"/></xsl:attribute>
<xsl:value-of select="Quantity"/>
</Quantity>
</Item>
</xsl:for-each>
</OrderForecastTimeSeries>
</xsl:if>

Edited by: Amol on Jul 21, 2009 3:26 AM

Accepted Solutions (0)

Answers (8)

Answers (8)

Former Member
0 Kudos

Hi Amol,

Refer to the link below. This will clear all your doubts:

[https://wiki.sdn.sap.com/wiki/display/Snippets/Convert%2bflat%2bXML%2bfile%2bto%2bnested%2busing%2bXSLT]

Warm Regards,

Anshul

anilekar
Participant
0 Kudos

thanks for the link Ansul. I will go through the link and will try to implement it.

Kai, I can't do that as its a flat file and Header, Record and Forecast are at same level. Thanks.

Regards

Amol

anilekar
Participant
0 Kudos

Hi All

Please let me know you inputs, Thanks.

Regards

Amol

Former Member
0 Kudos

Hi Amol,

Try the below mentioned and see if can achieve this:

Hi Amol,

Try to do it this way and see if it works:

In side loop for <xsl:for-each select = "/Record">

Dont use for-each for ForeCast.

Take the count of "ForeCast" by using the Count() function. Now use it as a predicate for ForeCast.

EG: /ForeCast [CountValue - (CountValue-i)]

Here i should be 1 and every time the loop is incremented, i should also increment by one.

Just try if you can achieve this.

Regards,

Anshul

Warm Regards,

Anshul

anilekar
Participant
0 Kudos

Hi Anshul

I think this should help me. Could you please brief more on this actually I am not aware of XSLT stuff that much, this is my first XSLT mapping. Thanks for your inputs.

Regards

Amol

Former Member
0 Kudos

Did you tried my last suggestion?

Your statement <xsl:for-each select="//Forecast"> gives back all elements on all levels! There's the issue!

Better use <xsl:for-each select="/Header/Record/Forecast">

This did not work?

Kai

anilekar
Participant
0 Kudos

Hi Anshul

I can't do that as Header Record and Forecast are at same level as its flat file. Please let me know if you need any information to help me out in resolving this issue. Thanks.

Regards

Amol

Former Member
0 Kudos

Hi Amol,

Using <xsl:for-each select="//Forecast"> will pick up all Forecast records no matter where they are present in the structure.

Instead you can use <xsl:for-each select="/Record/Forecast"> . This will take the Forecast element node under each Record element node and will give you the desired result.

Regards,

Anshul

Former Member
0 Kudos

Yeah - that's what I suggested.

Former Member
0 Kudos

Hi Amol,

Try to do it this way and see if it works:

In side loop for <xsl:for-each select = "/Header/Record">

Dont use for-each for ForeCast.

Take the count of "ForeCast" by using the Count() function. Now use it as a predicate for ForeCast.

EG: /Record/ForeCast[ CountValue - (CountValue-i) ]

Here i should be 1 and every time the loop is incremented, i should also increment by one.

Just try if you can achieve this.

Regards,

Anshul

Edited by: Anshul Chowdhary on Jul 21, 2009 11:20 AM

anilekar
Participant
0 Kudos

@kai

I can't do that as the data is part of Forecast Node in source file

@vijaya

my code mentioned above is already inside the record loop.

please let me know you inputs on the basis of above statments to resolve the issue. thanks

Regards

Amol

Former Member
0 Kudos

Your statement <xsl:for-each select="//Forecast"> gives back all elements on all levels! There's the issue!

Better use <xsl:for-each select="/Header/Record/Forecast">

This will work!

K

Edited by: Kai Lerch-Baier on Jul 21, 2009 11:18 AM

Former Member
0 Kudos

Hi,

First call the loop for <xsl:for-each select = "/Header/Record">

Inside that loop call <xsl:for-each select = "/ForeCast">

regards

Vijaykumar

Former Member
0 Kudos

Hi,

try to change this:

<xsl:for-each select="/Header/Record">

....

<xsl:value-of select="substring(ForecastDate,x,x)

...

<xsl:value-of select="substring(ForecastDate,x,x)

....

Regards,

Kai