xmlxsltxslt-1.0

XSLT Transformation: usage of Position and current using XSLT 1.0


This is input XML:

<deliveryStatusRequest>
    <Partner>
        <partyRoleId>A47422</partyRoleId>
        <Banner>
            <partyRoleId>A47423</partyRoleId>
            <POS>
                <partyRoleId>A47424</partyRoleId>
            </POS>
            <POS>
                <partyRoleId>A47425</partyRoleId>
            </POS>
        </Banner>
        <Banner>
            <partyRoleId>A47426</partyRoleId>
            <POS>
                <partyRoleId>A47428</partyRoleId>
            </POS>
        </Banner>
    </Partner>
    <ProcessData>
        <Partner>
            <returnCode>00</returnCode>
            <returnDescription>123456789</returnDescription>
            <Banner>
                <returnCode>00</returnCode>
                <returnDescription>234567890</returnDescription>
                <POS>
                    <returnCode>01</returnCode>
                    <returnDescription>Some error</returnDescription>
                </POS>
                <POS>
                    <returnCode>00</returnCode>
                    <returnDescription>456789012</returnDescription>
                </POS>
            </Banner>
            <Banner>
                <returnCode>00</returnCode>
                <returnDescription>567890123</returnDescription>
                <POS>
                    <returnCode>02</returnCode>
                    <returnDescription>Some Error</returnDescription>
                </POS>
            </Banner>
        </Partner>
    </ProcessData>
</deliveryStatusRequest>

This is expected output:

<SiebelMessage
                   MessageType="Integration Object"
                   IntObjectName="SFA Create Update Seller IO"
                   IntObjectFormat="Siebel Hierarchical">
    <ListOfSfaCreateUpdateSellerIo>
        <SfaSubAccountmasterBc>
            <CodiceSFA/> <!--Mapped to PartyRowId-->
            <CodiceSAP> <!--Mapped to returnDescription if returnCode is 00-->
            <StatoSAP> <!--"Attivo" If returnCode is 00 -->  
            <StatoCommerciale> <!-- "Attivo" If returnCode is 00 else set to "Prospect"-->
            <DescrizioneRitornoSAP> <!--Mapped to returnDescription if returnCode is not 00-->
            <ListOfSfaSubaccountInsegnaBc>
                <SfaSubaccountInsegnaBc>
                    <CodiceSFA/> <!--Mapped to PartyRowId-->
                    <CodiceSAP> <!--Mapped to returnDescription if returnCode is 00-->
                    <StatoSAP> <!--"Attivo" If returnCode is 00 -->  
                    <StatoCommerciale> <!-- "Attivo" If returnCode is 00 else set to "Prospect"-->
                    <DescrizioneRitornoSAP> <!--Mapped to returnDescription if returnCode is not 00-->
                    <ListOfSfaSubaccountPdvBc>
                        <SfaSubaccountPdvBc>                
                            <CodiceSFA/> <!--Mapped to PartyRowId-->
                            <CodiceSAP> <!--Mapped to returnDescription if returnCode is 00--
                            <StatoSAP> <!--"Attivo" If returnCode is 00 -->  
                            <StatoCommerciale> <!-- "Attivo" If returnCode is 00 else set to "Prospect"-->
                            <DescrizioneRitornoSAP> <!--Mapped to returnDescription if returnCode is not 00-->
                        </SfaSubaccountPdvBc>
                    </ListOfSfaSubaccountPdvBc>
                </SfaSubaccountInsegnaBc>
            </ListOfSfaSubaccountInsegnaBc>
        </SfaSubAccountmasterBc>
    </ListOfSfaCreateUpdateSellerIo>
</SiebelMessage>
                    

XSLT I've created, but it's not working:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="deliveryStatusRequest">
    <SiebelMessage MessageType="Integration Object" IntObjectName="SFA Create Update Seller IO" IntObjectFormat="Siebel Hierarchical">
      <ListOfSfaCreateUpdateSellerIo>
        <xsl:apply-templates select="Partner"/>
      </ListOfSfaCreateUpdateSellerIo>
    </SiebelMessage>
  </xsl:template>

  <xsl:template match="Partner">
    <SfaSubAccountmasterBc>
      <CodiceSFA><xsl:value-of select="partyRoleId"/></CodiceSFA>
      <CodiceSAP>
        <xsl:if test="../ProcessData/Partner/returnCode = '00'">
          <xsl:value-of select="../ProcessData/Partner/returnDescription"/>
        </xsl:if>
      </CodiceSAP>
      <StatoSAP>
          <xsl:if test="../ProcessData/Partner/returnCode = '00'">Attivo</xsl:if>
      </StatoSAP>
      <StatoCommerciale>
        <xsl:choose>
          <xsl:when test="../ProcessData/Partner/returnCode = '00'">Attivo</xsl:when>
          <xsl:otherwise>Prospect</xsl:otherwise>
        </xsl:choose>
      </StatoCommerciale>
      <DescrizioneRitornoSAP>
        <xsl:if test="../ProcessData/Partner/returnCode != '00'">
          <xsl:value-of select="../ProcessData/Partner/returnDescription"/>
        </xsl:if>
      </DescrizioneRitornoSAP>
      <ListOfSfaSubaccountInsegnaBc>
        <xsl:apply-templates select="Banner"/>
      </ListOfSfaSubaccountInsegnaBc>
    </SfaSubAccountmasterBc>
  </xsl:template>

  <xsl:template match="Banner">
    <SfaSubaccountInsegnaBc>
      <CodiceSFA><xsl:value-of select="partyRoleId"/></CodiceSFA>
      <xsl:variable name="bannerIndex" select="count(preceding-sibling::Banner) + 1"/>
      <CodiceSAP>
        <xsl:if test="../../ProcessData/Partner/Banner[$bannerIndex]/returnCode = '00'">
          <xsl:value-of select="../../ProcessData/Partner/Banner[$bannerIndex]/returnDescription"/>
        </xsl:if>
      </CodiceSAP>
      <StatoSAP>
          <xsl:if test="../../ProcessData/Partner/Banner[$bannerIndex]/returnCode = '00'">Attivo</xsl:if>
      </StatoSAP>
      <StatoCommerciale>
        <xsl:choose>
          <xsl:when test="../../ProcessData/Partner/Banner[$bannerIndex]/returnCode = '00'">Attivo</xsl:when>
          <xsl:otherwise>Prospect</xsl:otherwise>
        </xsl:choose>
      </StatoCommerciale>
      <DescrizioneRitornoSAP>
        <xsl:if test="../../ProcessData/Partner/Banner[$bannerIndex]/returnCode != '00'">
          <xsl:value-of select="../../ProcessData/Partner/Banner[$bannerIndex]/returnDescription"/>
        </xsl:if>
      </DescrizioneRitornoSAP>
      <ListOfSfaSubaccountPdvBc>
        <xsl:apply-templates select="POS"/>
      </ListOfSfaSubaccountPdvBc>
    </SfaSubaccountInsegnaBc>
  </xsl:template>

  <xsl:template match="POS">
    <SfaSubaccountPdvBc>
      <CodiceSFA><xsl:value-of select="partyRoleId"/></CodiceSFA>
      <xsl:variable name="bannerIndex" select="count(../../preceding-sibling::Banner) + 1"/>
      <xsl:variable name="posIndex" select="count(preceding-sibling::POS) + 1"/>
      <CodiceSAP>
        <xsl:if test="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnCode = '00'">
          <xsl:value-of select="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnDescription"/>
        </xsl:if>
      </CodiceSAP>
      <StatoSAP>
          <xsl:if test="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnCode = '00'">Attivo</xsl:if>
      </StatoSAP>
      <StatoCommerciale>
        <xsl:choose>
          <xsl:when test="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnCode = '00'">Attivo</xsl:when>
          <xsl:otherwise>Prospect</xsl:otherwise>
        </xsl:choose>
      </StatoCommerciale>
      <DescrizioneRitornoSAP>
        <xsl:if test="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnCode != '00'">
          <xsl:value-of select="../../../../ProcessData/Partner/Banner[$bannerIndex]/POS[$posIndex]/returnDescription"/>
        </xsl:if>
      </DescrizioneRitornoSAP>
    </SfaSubaccountPdvBc>
  </xsl:template>
</xsl:stylesheet>

I'm getting output like this, Under POS it's not mapping the output correctly. It's not even mapping ReturnDescription to Description tag.

<?xml version="1.0" encoding="UTF-8"?>
<SiebelMessage MessageType="Integration Object"
               IntObjectName="SFA Create Update Seller IO"
               IntObjectFormat="Siebel Hierarchical">
   <ListOfSfaCreateUpdateSellerIo>
      <SfaSubAccountmasterBc>
         <CodiceSFA>A47422</CodiceSFA>
         <CodiceSAP>123456789</CodiceSAP>
         <StatoSAP>Attivo</StatoSAP>
         <StatoCommerciale>Attivo</StatoCommerciale>
         <DescrizioneRitornoSAP/>
         <ListOfSfaSubaccountInsegnaBc>
            <SfaSubaccountInsegnaBc>
               <CodiceSFA>A47423</CodiceSFA>
               <CodiceSAP>234567890</CodiceSAP>
               <StatoSAP>Attivo</StatoSAP>
               <StatoCommerciale>Attivo</StatoCommerciale>
               <DescrizioneRitornoSAP/>
               <ListOfSfaSubaccountPdvBc>
                  <SfaSubaccountPdvBc>
                     <CodiceSFA>A47424</CodiceSFA>
                     <CodiceSAP/>
                     <StatoSAP/>
                     <StatoCommerciale>Prospect</StatoCommerciale>
                     <DescrizioneRitornoSAP/>
                  </SfaSubaccountPdvBc>
                  <SfaSubaccountPdvBc>
                     <CodiceSFA>A47425</CodiceSFA>
                     <CodiceSAP/>
                     <StatoSAP/>
                     <StatoCommerciale>Prospect</StatoCommerciale>
                     <DescrizioneRitornoSAP/>
                  </SfaSubaccountPdvBc>
               </ListOfSfaSubaccountPdvBc>
            </SfaSubaccountInsegnaBc>
            <SfaSubaccountInsegnaBc>
               <CodiceSFA>A47426</CodiceSFA>
               <CodiceSAP>567890123</CodiceSAP>
               <StatoSAP>Attivo</StatoSAP>
               <StatoCommerciale>Attivo</StatoCommerciale>
               <DescrizioneRitornoSAP/>
               <ListOfSfaSubaccountPdvBc>
                  <SfaSubaccountPdvBc>
                     <CodiceSFA>A47428</CodiceSFA>
                     <CodiceSAP/>
                     <StatoSAP/>
                     <StatoCommerciale>Prospect</StatoCommerciale>
                     <DescrizioneRitornoSAP/>
                  </SfaSubaccountPdvBc>
               </ListOfSfaSubaccountPdvBc>
            </SfaSubaccountInsegnaBc>
         </ListOfSfaSubaccountInsegnaBc>
      </SfaSubAccountmasterBc>
   </ListOfSfaCreateUpdateSellerIo>
</SiebelMessage>

This is the logic: CodiceSAP for POS: Populate CodiceSAP if returnCode = '00'. DescrizioneRitornoSAP for POS: Populate only when returnCode != '00'. StatoSAP and StatoCommerciale for POS: Set to Attivo when returnCode = '00'; otherwise, default "" (StatoSAP) and "Prospect" (for StatoCommerciale).


Solution

  • I think you need to move one level .. up higher to populate CodiceSAP e.g.

       <xsl:template match="Banner">
            <SfaSubaccountInsegnaBc>
                <CodiceSFA>
                    <xsl:value-of select="partyRoleId"/>
                </CodiceSFA>
                <CodiceSAP>
                    <xsl:choose>
                        <xsl:when test="../../ProcessData/Partner/Banner[position() = count(preceding-sibling::Banner) + 1]/returnCode = '00'">
                            <xsl:value-of select="../../ProcessData/Partner/Banner[position() = count(preceding-sibling::Banner) + 1]/returnDescription"/>
                        </xsl:when>
                    </xsl:choose>
                </CodiceSAP>
    

    For the POS elements, your code was looking at one level to high, i.e. it seems you rather wanted

        <xsl:template match="POS">
            <SfaSubaccountPdvBc>
                <CodiceSFA>
                    <xsl:value-of select="partyRoleId"/>
                </CodiceSFA>
                <CodiceSAP>
                    <xsl:choose>
                        <xsl:when test="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnCode = '00'">
                            <xsl:value-of select="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnDescription"/>
                        </xsl:when>
                    </xsl:choose>
                </CodiceSAP>
                <StatoSAP>
                    <xsl:choose>
                        <xsl:when test="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnCode = '00'">Attivo</xsl:when>
                    </xsl:choose>
                </StatoSAP>
                <StatoCommerciale>
                    <xsl:choose>
                        <xsl:when test="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnCode = '00'">Attivo</xsl:when>
                        <xsl:otherwise>Prospect</xsl:otherwise>
                    </xsl:choose>
                </StatoCommerciale>
                <DescrizioneRitornoSAP>
                    <xsl:choose>
                        <xsl:when test="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnCode != '00'">
                            <xsl:value-of select="../../../ProcessData/Partner/Banner[position() = count(../../preceding-sibling::Banner) + 1]/POS[position() = count(preceding-sibling::POS) + 1]/returnDescription"/>
                        </xsl:when>
                    </xsl:choose>
                </DescrizioneRitornoSAP>
            </SfaSubaccountPdvBc>
        </xsl:template>