Question

I need to transform SAP IDOC xml into AdsML format. But the abstract question is: how to transform xml1 into xml2?

xml1:

<E1BPBUSISM008_ITEM_OUT>
    <ITEM_NUMBER>010</ITEM_NUMBER>
</E1BPBUSISM008_ITEM_OUT>
<E1BPBUSISM008_ITEM_OUT>
    <ITEM_NUMBER>020</ITEM_NUMBER> 
</E1BPBUSISM008_ITEM_OUT>

<E1BPBUSISM008_AD_SPEC_AD_OU>
    <ITEM_NUMBER>010</ITEM_NUMBER>
    <PLANNED_WIDTH>1.851</PLANNED_WIDTH>
    <PLANNED_HEIGHT>0.000</PLANNED_HEIGHT>
</E1BPBUSISM008_AD_SPEC_AD_OU>
<E1BPBUSISM008_AD_SPEC_AD_OU>
    <ITEM_NUMBER>020</ITEM_NUMBER>  
    <PLANNED_WIDTH>2.37</PLANNED_WIDTH>
    <PLANNED_HEIGHT>0.000</PLANNED_HEIGHT>
</E1BPBUSISM008_AD_SPEC_AD_OU>

into xml2:

<Ad>
    <ad-number>010<ad-number>
    <width>1.851</width>
    <height>0.000</height>
</Ad>
<Ad>
    <ad-number>020<ad-number>
    <width>2.37</width>
    <height>0.000</height>
</Ad>

What I have tried here is Muench method, but even if it is the correct solution for this case, not sure how to complete it, because it returns wrong 'width' and 'heigth' (the same for all Ad elements):

<xsl:key name="adnumbers" match="IE1BPBUSISM008_ITEM_OUT" use="ITEM_NUMBER"/>
....
<xsl:for-each select="E1BPBUSISM008_ITEM_OUT[generate-id(.)=generate-id(key('adnumbers',ITEM_NUMBER)[1])]">
<xsl:sort select="ITEM_NUMBER"/>
<Ad>
<ad-number>
    <xsl:value-of select="ITEM_NUMBER/text()"/>
</ad-number>
<width>
<xsl:value-of select="E1BPBUSISM008_AD_SPEC_AD_OU/PLANNED_WIDTH"/>
</width>
<height>
<xsl:value-of select="E1BPBUSISM008_AD_SPEC_AD_OU/PLANNED_HEIGHT"/>
</height>

outputs:

<Ad>
  <number>010</ad-number>
  <width>1.851</width>
  <heigth>0.000</heigth>
</Ad>
<Ad>
  <number>020</ad-number>
  <width>1.851</width>
  <heigth>0.000</heigth>
</Ad>
Was it helpful?

Solution

You will not need actual Muenchian Grouping - using the key will be sufficient to get the desired result.

<xsl:key name="k_AD_SPEC_AD_OU" match="E1BPBUSISM008_AD_SPEC_AD_OU" use="ITEM_NUMBER" />

<!-- ... -->

<xsl:for-each select="E1BPBUSISM008_ITEM_OUT">
    <xsl:sort select="ITEM_NUMBER" />
    <Ad>
        <ad-number>
            <xsl:value-of select="ITEM_NUMBER" />
        </ad-number>
        <width>
            <xsl:value-of select="key('k_AD_SPEC_AD_OU', ITEM_NUMBER)[1]/PLANNED_WIDTH" />
        </width>
        <height>
            <xsl:value-of select="key('k_AD_SPEC_AD_OU', ITEM_NUMBER)[1]/PLANNED_HEIGHT" />
        </height>
    </Ad>
</xsl:for-each>

<!-- ... -->

However the correct solution depends on the relation between your E1BPBUSISM008_ITEM_OUT and E1BPBUSISM008_AD_SPEC_AD_OU: Your example suggests that it is simply 1 to 1 which would make the key unnecessary but I suspect that your actual relation might be rather 1 to 0 or 1 or even 1 to 0 or more.

If you need to create output for missing E1BPBUSISM008_AD_SPEC_AD_OU elements (1 to 0 or 1 relation) the xslt will need some tweaking.


For a simple 1 to 1 relation your xslt could look like this:

<!-- ... -->

<xsl:for-each select="E1BPBUSISM008_ITEM_OUT">
    <xsl:sort select="ITEM_NUMBER" />
    <Ad>
        <ad-number>
            <xsl:value-of select="ITEM_NUMBER" />
        </ad-number>

        <xsl:call-template name="AD_SPEC_AD_OU">
            <xsl:with-param name="pITEM_NUMBER" select="ITEM_NUMBER" />
        </xsl:call-template>
    </Ad>
</xsl:for-each>

<xsl:template name="AD_SPEC_AD_OU">
    <xsl:param name="pITEM_NUMBER" />

    <width>
        <xsl:value-of select="//E1BPBUSISM008_AD_SPEC_AD_OU[ITEM_NUMBER = $pITEM_NUMBER]/PLANNED_WIDTH" />
    </width>
    <height>
        <xsl:value-of select="//E1BPBUSISM008_AD_SPEC_AD_OU[ITEM_NUMBER = $pITEM_NUMBER]/PLANNED_HEIGHT" />
    </height>
</xsl:template>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top