4 Replies Latest reply on Dec 14, 2009 4:13 PM by Stevo-6112

    XSL Many to Singles

    Stevo-6112
      I am using jdeveloper transformations and need to get from INPUT to OUTPUT but can't seen to get the desired result:
      ----------- INPUT ---------------------------       ------------------- OUTPUT --------------
      <Note type="INSPECTION_REQUIRED_FLAG">N</Note>      <INSPECTION_REQUIRED_FLAG>N</INSPECTION_REQUIRED_FLAG>
      <Note type="RECEIPT_REQUIRED_FLAG">Y</Note>         <RECEIPT_REQUIRED_FLAG>Y</RECEIPT_REQUIRED_FLAG>
      It seems like jdeveloper only allows single nodes inside the for-each so I for-each the <Note> twice, once for each output node and use an if or choose to match the type attribute. However this only populates one of the output nodes, usually the last one and sometimes it duplicates it.
      <xsl:for-each select="/ns0:PurchaseOrderLine/ns0:Note">
        <xsl:if test='xp20:matches(/ns0:PurchaseOrderLine/ns0:Note/@type,"INSPECTION_REQUIRED_FLAG")'>
          <ESC:INSPECTION_REQUIRED_FLAG>
            <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note"/>
            </ESC:INSPECTION_REQUIRED_FLAG>
        </xsl:if>
      </xsl:for-each>
      
      <xsl:for-each select="/ns0:PurchaseOrderLine/ns0:Note">
        <xsl:if test='xp20:matches(/ns0:PurchaseOrderLine/ns0:Note/@type,"RECEIPT_REQUIRED_FLAG")'>
          <ESC:RECEIPT_REQUIRED_FLAG>
            <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note"/>
          </ESC:RECEIPT_REQUIRED_FLAG>
        </xsl:if>
      </xsl:for-each>
      Full paths removed for readability.

      Thanks...
        • 1. Re: XSL Many to Singles
          PrazzyJay
          try this

          <xsl:for-each select="/ns0:PurchaseOrderLine/ns0:Note">
          <xsl:if test='xp20:matches(/ns0:PurchaseOrderLine/ns0:Note/@type,"INSPECTION_REQUIRED_FLAG")'>
          <ESC:INSPECTION_REQUIRED_FLAG>
          <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note"/>
          </ESC:INSPECTION_REQUIRED_FLAG>
          </xsl:if>
          <xsl:if test='xp20:matches(/ns0:PurchaseOrderLine/ns0:Note/@type,"RECEIPT_REQUIRED_FLAG")'>
          <ESC:RECEIPT_REQUIRED_FLAG>
          <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note"/>
          </ESC:RECEIPT_REQUIRED_FLAG>
          </xsl:if>
          </xsl:for-each>


          --Prasanna                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
          • 2. Re: XSL Many to Singles
            723381
            What if the number of Note elements varies?

            Thanks-
            iBizTrack.com
            • 3. Re: XSL Many to Singles
              Stevo-6112
              I found out from another post that this can be done as shown below however in jdeveloper it has to be done by hand in the source unless you drag in an XPath component which does the same thing. I think the XPath is in the Advanced Functions components.
              <ESC:INSPECTION_REQUIRED_FLAG>
                  <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note[@type='INSPECTION_REQUIRED_FLAG']"/>
              </ESC:INSPECTION_REQUIRED_FLAG>
               
              <ESC:RECEIPT_REQUIRED_FLAG>
                  <xsl:value-of select="/ns0:PurchaseOrderLine/ns0:Note[@type='RECEIPT_REQUIRED_FLAG']"/>
              </ESC:RECEIPT_REQUIRED_FLAG>
              Therefore if there are multiple notes. The only ones that getted mapped to the target are the ones you have coded for. This requires you to know all possible "types" that you will need.
              • 4. Re: XSL Many to Singles
                Stevo-6112
                Here's something I"ve noticed in the behavior of jdeveloper xsl. When I do a for-each, it sometimes uses a "." to set the path of the "value-of select" and sometimes uses the full path. This "." returns the expected value of the match, whereas the full notation as shown in the second code box, returns the first value in the multiple list.

                I guess this is logical since the "." probably refers to the current record being looped thru, and the full notation probably refers to the entire group which returns the first result. But not sure how jdeveloper knows when to use which so doing it in the source may be necessary.
                {code}
                Get the Amount from these
                ----------------------------------------------------
                <expression>/Credit/Note[.="Best Seller"]</expression>
                <expression>/Credit/Description[.="Book"]</expression>
                <expression>/Credit/Amount[.="40"]</expression>
                {code}

                {code}
                BOX 1 USING DOT - Returns expected Matched value
                ----------------------------------------------------
                <xsl:for-each select="/ns0:GetCredit/ns0:DataArea/ns0:Get/ns0:Expression">
                <xsl:choose>
                <xsl:when test='xp20:matches(.,".*Amount.*")'>
                <ESC:Amount>
                <xsl:value-of select='substring-before(substring-after(.,"=&amp;quot;"),"&amp;quot;]")'/>
                </ESC:Amount>
                </xsl:when>
                </xsl:choose>
                </xsl:for-each>
                {code}

                {code}
                BOX 2 USING FULL NOTATION - returns first in list
                ----------------------------------------------------
                <xsl:for-each select="/ns0:GetCredit/ns0:DataArea/ns0:Get/ns0:Expression">
                <xsl:choose>
                <xsl:when test='xp20:matches(.,".*Amount.*")'>
                <ESC:Amount>
                <xsl:value-of select='substring-before(substring-after(/ns0:GetCredit/ns0:DataArea/ns0:Get/ns0:Expression,"=&amp;quot;"),"&amp;quot;]")'/>
                </ESC:Amount>
                </xsl:when>
                </xsl:choose>
                </xsl:for-each>
                {code}