This discussion is archived
1 2 Previous Next 16 Replies Latest reply: Jul 18, 2012 6:07 PM by Venkatesh Ramasamy RSS

Re-Assign variable in XSL

Venkatesh Ramasamy Newbie
Currently Being Moderated
Hello,

I am trying to check for a condition in an XSL transform and reassign a variable, I have understood that reassigning a variable is not an option in functional programming. However the need is that I need to check for a condition and then reassign a variable with a new value, is there any other option or ways of doing this. I have given the part of the code below. The variable varBoxID is initialized to "0", the If the Box# != varBoxID, then re-assign the variable varBoxID to the value of the variable "TempBoxID".

Any ideas / suggestions are greatly appreciated.


*<xsl:variable name="varBoxID">0</xsl:variable>* (Initializing a value to a variable)
<xsl:variable name="TempBoxId"
select="/tns:OrderDetails/tns:Order/tns:BoxNo"/>
<xsl:if test="/tns:OrderDetails/tns:Order/tns:BoxNo != $varBoxID">
<ns2:package_Data>
<ns0:package_id>
<xsl:value-of select="/tns:OrderDetails/tns:Order/tns:BoxNo"/>
</ns0:package_id>
<xsl:for-each select="/tns:OrderDetails/tns:Order">
<xsl:if test="tns:BoxNo != $varBoxID">
*<xsl:variable name="varBoxID"*
select="/tns:OrderDetails/tns:Order/TempBoxID"/> (Re-assigning a value to the previously declared variable)
<ns0:package_Items>
<ns0:vendor_item_number>
<xsl:value-of select="tns:SKU"/>
</ns0:vendor_item_number>
<ns0:quantity_shipped>
<xsl:value-of select="tns:QtyShipped"/>
</ns0:quantity_shipped>
</ns0:package_Items>
</xsl:if>
</xsl:if>
</xsl:for-each>

Thanks,
Venkatesh
  • 1. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    Hi Venkatesh,
    I need to check for a condition and then reassign a variable with a new value
    I don't think you need that "reassign" in order to do what you're trying to do... I reckon you're thinking procedural, not functional...

    I think that you have this:
    <OrderDetails>
         <Order>
              <BoxNo>111</BoxNo>
              <SKU>sku1_1</SKU>
              <QtyShipped>11</QtyShipped>
         </Order>
         <Order>
              <BoxNo>111</BoxNo>
              <SKU>sku1_1</SKU>
              <QtyShipped>12</QtyShipped>
         </Order>
         <Order>
              <BoxNo>222</BoxNo>
              <SKU>sku2_2</SKU>
              <QtyShipped>21</QtyShipped>
         </Order>
         <Order>
              <BoxNo>222</BoxNo>
              <SKU>sku2_2</SKU>
              <QtyShipped>22</QtyShipped>
         </Order>
    </OrderDetails>
    And wanna change into this:
    <root>
         <package_Data>
              <package_id>111</package_id>
              <package_Items>
                   <vendor_item_number>sku1_1</vendor_item_number>
                   <quantity_shipped>11</quantity_shipped>
              </package_Items>
              <package_Items>
                   <vendor_item_number>sku1_2</vendor_item_number>
                   <quantity_shipped>12</quantity_shipped>
              </package_Items>
         </package_Data>
         <package_Data>
              <package_id>111</package_id>
              <package_Items>
                   <vendor_item_number>sku1_1</vendor_item_number>
                   <quantity_shipped>11</quantity_shipped>
              </package_Items>
              <package_Items>
                   <vendor_item_number>sku1_2</vendor_item_number>
                   <quantity_shipped>12</quantity_shipped>
              </package_Items>
         </package_Data>
    </root>
    Is that your requirement? Tell me if that's the idea and we can work from there.

    Cheers,
    Vlad
  • 2. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    Thanks for the reply, Here is the source, This order has 2 SKU's (SKU 1 - Qty 2 & SKU 2 - Qty 1). Both the Items for SKU 1 goes in one package and SKU 2 with Qty1 goes in a separate package.

    This is source xml from the CSV file.

    <OrderDetails>
         <Order>
              <PurchaseOrderNumber>2245</PurchaseOrderNumber>
              <RefNum>648289656</RefNum>
              <OrderStatus>Shipped</OrderStatus>
              <SKU>1</SKU>
              <Qty>2</Qty>
              <TotalNoBoxes>2</TotalNoBoxes>
              <BoxNo>1</BoxNo>          
              <TrackingNumber>1z12346r546907</TrackingNumber>          
         </Order>
         <Order>
              <PurchaseOrderNumber>2245</PurchaseOrderNumber>
              <RefNum>648289656</RefNum>
              <OrderStatus>Shipped</OrderStatus>
              <SKU>1</SKU>
              <Qty>2</Qty>
              <TotalNoBoxes>2</TotalNoBoxes>
              <BoxNo>1</BoxNo>          
              <TrackingNumber>1z12346r546907</TrackingNumber>
         </Order>
    <Order>
              <PurchaseOrderNumber>2245</PurchaseOrderNumber>
              <RefNum>648289656</RefNum>
              <OrderStatus>Shipped</OrderStatus>
              <SKU>2</SKU>
              <Qty>1</Qty>
              <TotalNoBoxes>2</TotalNoBoxes>
              <BoxNo>2</BoxNo>          
              <TrackingNumber>1z12346r546908</TrackingNumber>
         </Order>
    </OrderDetails>

    The above source needs to be transformed in to the following.
    <root>
    <ns2:package_Data>
         <ns0:package_id>1</ns0:package_id>
         <ns0:package_Items>
              <ns0:vendor_item_number>1</ns0:vendor_item_number>
              <ns0:quantity_shipped>3</ns0:quantity_shipped>
         </ns0:package_Items>
         <ns0:trackingNumber>1z12346r546907</ns0:trackingNumber>
    </ns2:package_Data>

    <ns2:package_Data>
         <ns0:package_id>2</ns0:package_id>
         <ns0:package_Items>
              <ns0:vendor_item_number>2</ns0:vendor_item_number>
              <ns0:quantity_shipped>1</ns0:quantity_shipped>
         </ns0:package_Items>
         <ns0:trackingNumber>1z12346r546908</ns0:trackingNumber>
    </ns2:package_Data>
    </root>

    If all the items goes in one box, the transform should look like this,

    <root>
    <ns2:package_Data>
         <ns0:package_id>1</ns0:package_id>
         <ns0:package_Items>
              <ns0:vendor_item_number>1</ns0:vendor_item_number>
              <ns0:quantity_shipped>3</ns0:quantity_shipped>
         </ns0:package_Items>
         <ns0:package_Items>
              <ns0:vendor_item_number>2</ns0:vendor_item_number>
              <ns0:quantity_shipped>1</ns0:quantity_shipped>
         </ns0:package_Items>
         <ns0:trackingNumber>1z12346r546907</ns0:trackingNumber>
    </ns2:package_Data>

    I appreciate your help, thanks,
    Venkatesh
  • 3. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    Hi Venkatesh,

    Make sure you are using XSLT 2.0
    <xsl:stylesheet version="2.0"
    and include the xpath-functions namespace
                    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    Your transformation will be like this:
      <xsl:template match="/">
        <root>
          <xsl:for-each select="fn:distinct-values(/ns0:OrderDetails/ns0:Order/ns0:BoxNo/text())">
            <xsl:variable name="boxNo" select="."/>
              <ns1:package_Data>
                <ns1:package_id>
                  <xsl:value-of select="$boxNo"/>
                </ns1:package_id>
                <xsl:for-each select="/ns0:OrderDetails/ns0:Order[ns0:BoxNo = $boxNo]">
                  <ns1:package_Items>
                    <ns1:vendor_item_number>
                      <xsl:value-of select="ns0:SKU"/>
                    </ns1:vendor_item_number>
                    <ns1:quantity_shipped>
                      <xsl:value-of select="ns0:QtyShipped"/>
                    </ns1:quantity_shipped>
                  </ns1:package_Items>
                </xsl:for-each>
              </ns1:package_Data>
          </xsl:for-each>
        </root>
      </xsl:template>
    Let me know if that works.

    Cheers,
    Vlad
  • 4. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    Thank You Vlad,

    That worked perfectly fine, I appreciate your help, however, I could no longer use the design view of the transform. I get the following error on every line where i have used "fn:distinct-values".

    Line Number:(55) : Invalid XPath expression(null).

    This error occurs every time I switch from source view to design view.

    The version of JDeveloper I am using is Studio Edition Version 11.1.1.4.0

    Is this a problem with the JDeveloper 11.1.1.4.0 not compatible with XSL 2.0?

    Thanks,
    Venkatesh
  • 5. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    That worked perfectly fine, I appreciate your help...
    Would you mind marking answers accordingly... Helpful or correct?
    https://forums.oracle.com/forums/ann.jspa?annID=330
  • 6. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    I have marked the question as answered. Regarding my other question about the error when trying to open the transform in design mode, do you see that as a problem with the Jdeveloper?

    Here is my question.

    I could no longer use the design view of the transform. I get the following error on every line where i have used "fn:distinct-values".

    Line Number:(55) : Invalid XPath expression(null).

    This error occurs every time I switch from source view to design view.

    The version of JDeveloper I am using is Studio Edition Version 11.1.1.4.0

    Is this a problem with the JDeveloper 11.1.1.4.0 not compatible with XSL 2.0?

    Thanks,
    Venkatesh
  • 7. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    That's interesting, BPEL supports XSLT 2.0 as we just proved, but not sure about the design view on JDev.

    I'll do some research and let you know.

    Cheers,
    Vlad
  • 8. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    JDev is backed up by XDK - Oracle® XML Developer's Kit that does support XSLT 2.0, but according to the references bellow the support is partial...

    XSLT 2.0 (working draft dated 04 April 2005) Partial

    XDK Standards
    http://docs.oracle.com/cd/E12839_01/appdev.1111/b28394/adx_ref_standards.htm

    Using the XSLT Processor for Java
    http://docs.oracle.com/cd/E12839_01/appdev.1111/b28394/adx_j_xslt.htm

    Pity, it seems like you have the functionality, but you loose the design view...

    Cheers,
    Vlad
  • 9. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    Hi Vlad,

    Thanks for all your help.

    I am using the fn:distinct-values in to my xsl to convert to the required format, this works perfectly fine for just one order in a csv file. When I passed a file with more than one Order and has multiple lines for an order I got the below output. I did a for-each distinct values at the order level and ended up with the following, Could you please guide me to a right direction.

    1. All unique order numbers lined up in One node (<ns2:order_number>648290074 648290075 648290076 648290077 648290079</ns2:order_number> vs <ns2:order_number>648290074</ns2:order_number> for each order)
    2. The Item Data from all orders were listed in every order (The expectation is only to list the relevant lines for the order (I am not sure how to get that separated by order number)

    I am not sure how to separate data for a specific order? I think there should be some function to strip off the irrelevant data given a condition, however, not sure.


    Thanks,
    Venkatesh
  • 10. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    I am using the fn:distinct-values
    Yes, you're probably using it too much... It should be used once for each key value... How many keys do you have?

    Where you see:
    <ns2:order_number>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails/tns:PurchaseOrderNumber/text())"/>
    </ns2:order_number>
    Change to:
    <ns2:order_number>
    <xsl:value-of select="."/>
    </ns2:order_number>
    Please let me know if this was helpful...

    Cheers,
    Vlad
  • 11. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    Thanks, That was really helpful. The OrderNumber element is fixed now. However, when I removed the distinct-values, I am seeing everything in to that element, like this,

    <ns2:order_inv_number>648291561 648291562 648291562</ns2:order_inv_number>
    <ns2:order_inv_amt>17 47 47</ns2:order_inv_amt>

    by using distinct-values, I end up getting like this,

    <ns2:order_inv_number>648291561 648291562</ns2:order_inv_number>
    <ns2:order_inv_amt>17 47</ns2:order_inv_amt>

    What I want is

    <order>
    <ns2:order_inv_number>648291561</ns2:order_inv_number>
    <ns2:order_inv_amt>17</ns2:order_inv_amt>
    </order>
    <order>
    <ns2:order_inv_number>648291562</ns2:order_inv_number>
    <ns2:order_inv_amt>47</ns2:order_inv_amt>
    </order>

    To answer your question of How many keys do I have?, Could you please explain what you refer as key, I am completely new to xsl and I am trying to learn as much as possible, and I greatly appreciate your time and patience in helping me understand.

    Thanks,
    Venkatesh

    Edited by: Venkatesh on Jul 17, 2012 11:12 PM
  • 12. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    Hi,

    What I mean by key, is the unique identifier field, what in your case I believe is the order number... So you have to iterate your order using for-each and make all the rest refer to this order...

    Where you see this...
    <xsl:if test="/tns:DailySummary/tns:OrderDetails[tns:PurchaseOrderNumber = $tmpOrderNo]">
    <ns2:order_inv_number>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails/tns:InvoiceNumber/text())"/>
    </ns2:order_inv_number>
    <ns2:order_inv_amt>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails/tns:InvoiceAmt/text())"/>
    </ns2:order_inv_amt>
    <ns2:order_freight_charge>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails/tns:FreightCharge/text())"/>
    </ns2:order_freight_charge>
    </xsl:if>
    Replace with this
    <ns2:order_inv_number>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails[tns:PurchaseOrderNumber = $tmpOrderNo]/tns:InvoiceNumber/text())"/>
    </ns2:order_inv_number>
    <ns2:order_inv_amt>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails[tns:PurchaseOrderNumber = $tmpOrderNo]/tns:InvoiceAmt/text())"/>
    </ns2:order_inv_amt>
    <ns2:order_freight_charge>
    <xsl:value-of select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails[tns:PurchaseOrderNumber = $tmpOrderNo]/tns:FreightCharge/text())"/>
    </ns2:order_freight_charge>
    You almost getting there, but the xsl:if won't work as you're thinking... Note that I've removed it... Remember this is a functional language, not a procedural one...

    I think you can go from there, please let me know if this was helpful

    Cheers,
    Vlad
  • 13. Re: Re-Assign variable in XSL
    vladodias Guru
    Currently Being Moderated
    Also your variable definition is not right...

    Where you see this
    <xsl:variable name="tmpOrderNo" select="fn:distinct-values(/tns:DailySummary/tns:OrderDetails/tns:PurchaseOrderNumber/text())"/>
    Replace with this
    <xsl:variable name="tmpOrderNo" select="."/>
    Otherwise the code above won't work...

    Cheers,
    Vlad
  • 14. Re: Re-Assign variable in XSL
    Venkatesh Ramasamy Newbie
    Currently Being Moderated
    Hi Vlad,

    That was really helpful. I think it's taking time for me to think functionally, and I am working hard to get there. I appreciate your help and guidance.

    I am almost done with this however, I am encountering a problem, I hope it's not too bad, for example, if a value in the input xml is same in same/multiple orders, the unique values gets appended in the same node, in the below example, I have an order with SKU "2" with Qty "1" and SKU "4" with Qty "2", so, my csv file will come with 3 lines, 1 line for SKU "2" and 2 lines for SKU4. The output seems to append both the distinct values (like <ns0:quantity_ordered>*1 2*</ns0:quantity_ordered>) in the same node as shown in the example below. I don't know whether I am using a wrong key in the Item_Data or something else,


    I believe, I am not using the right condition to check for the distinct SKU or using a wron for-each condition, I am not sure if that is the problem. I would appreciate if you could point me to the problem.

    Thanks,
    Venkatesh

    Edited by: Venkatesh on Jul 19, 2012 12:23 AM
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points