14 Replies Latest reply on Jan 22, 2017 7:22 PM by beverly

    xsl: variable name

    rrighini

      HI all,

       

      I'm trying to export some data using the following xsl set up but every time I try to export the data filemaker tells me that variable name or parameter has already been assigned so I can't use it to export the grandchild data in "additional payments".  I know one of you will know the solution to my problem and I'll be eternally grateful.

       

      Here's my stylesheet

      <ContractOrServiceGroup>

          <ContractOrService>

           <xsl:for-each select="fm:PayrollNo/fm:DATA">

                <xsl:variable name="pos" select="position()"/>

            <ContractType><xsl:value-of select="../../fm:ContractType/fm:DATA[$pos]" /></ContractType>

            <ContractStart><xsl:value-of select="../../fm:ContractStart/fm:DATA[$pos]" /></ContractStart>   

            <ContractEnd><xsl:value-of select="../../fm:ContractEnd/fm:DATA[$pos]" /></ContractEnd>

            <Post><xsl:value-of select="../../fm:ContractPost/fm:DATA[$pos]" /></Post>

            <SchoolArrivalDate><xsl:value-of select="../../fm:SchoolArrivalDate/fm:DATA[$pos]" /></SchoolArrivalDate>

            <DailyRate><xsl:value-of select="../../fm:DailyRate/fm:DATA[$pos]" /></DailyRate>

            <DestinationCode><xsl:value-of select="../../fm:DestinationCode/fm:DATA[$pos]" /></DestinationCode>

            <Origin><xsl:value-of select="../../fm:Origin/fm:DATA[$pos]" /></Origin>

            <PayReviewDate><xsl:value-of select="../../fm:PayReviewDate/fm:DATA[$pos]" /></PayReviewDate>

            <LASchoolLevel><xsl:value-of select="../../fm:LASchoolLevel/fm:DATA[$pos]" /></LASchoolLevel>    

           <PostLevelDetails>

            <Payments>

             <PayRange><xsl:value-of select="../../fm:PayRange/fm:DATA[$pos]" /></PayRange>

             <PayFramework><xsl:value-of select="../../fm:LeadershipPayFramework/fm:DATA[$pos]" /></PayFramework>

             <PayRangeMinimum><xsl:value-of select="../../fm:LeadershipPayRangeMinimum/fm:DATA[$pos]" /></PayRangeMinimum>

             <PayRangeMaximum><xsl:value-of select="../../fm:LeadershipPayRangeMaximum/fm:DATA[$pos]" /></PayRangeMaximum>

             <BasePay><xsl:value-of select="../../fm:BasePay/fm:DATA[$pos]" /></BasePay>

             <SafeguardedSalary><xsl:value-of select="../../fm:SafeguardedSalary/fm:DATA[$pos]" /></SafeguardedSalary>

            </Payments>

            <AdditionalPayments>

             <AdditionalPayment>

              <xsl:for-each select="fm:AdditionalPaymentType/fm:DATA">

              <xsl:variable name="pos" select="position()"/>

              <PaymentType><xsl:value-of select="../../fm:AdditionalPaymentType/fm:DATA[$pos]" /></PaymentType>

              <PaymentAmount><xsl:value-of select="../../fm:AdditionalPaymentAmount/fm:DATA[$pos]" /></PaymentAmount>

              <PayStartDate><xsl:value-of select="../../fm:AdditionalPaymentStartDate/fm:DATA[$pos]" /></PayStartDate>

              <PayEndDate><xsl:value-of select="../../fm:AdditionalPaymentEndDate/fm:DATA[$pos]" /></PayEndDate>

             </xsl:for-each>

             </AdditionalPayment>

            </AdditionalPayments>

           

           </PostLevelDetails>

           </xsl:for-each>

          </ContractOrService>

         </ContractOrServiceGroup>

        

       

       

       

      With thanks

        • 1. Re: xsl: variable name
          beverly

          What does the raw XML export look like (without the xslt)?

           

          It's difficult to see just from the XSLT.

           

          Sent from miPhone

          • 2. Re: xsl: variable name
            rrighini

            <SchoolWorkforceMember>

            <StaffDetails>

            <TeacherNumber>9127/47654 </TeacherNumber>

            <StaffMemberName>

            <PersonFamilyName>Smith</PersonFamilyName>

            <GivenNames>

            <GivenName>

            <PersonGivenName>Bill</PersonGivenName>

            </GivenName>

            </GivenNames>

            </StaffMemberName>

            <FormerFamilyNames>

            <PersonFamilyName/>

            </FormerFamilyNames>

            <NINumber>NN123456</NINumber>

            <GenderCurrent>Male</GenderCurrent>

            <PersonBirthDate/>

            <Ethnicity>NOBT</Ethnicity>

            <Disability>NOBT</Disability>

            <QTStatus>True</QTStatus>

            <HLTAStatus/>

            <QTSRoute>False</QTSRoute>

            </StaffDetails>

            <ContractOrServiceGroup>

            <ContractOrService>

            <ContractType>Perm</ContractType>

            <ContractStart>01/06/2006</ContractStart>

            <ContractEnd/>

            <Post>UPR</Post>

            <SchoolArrivalDate>01/01/1999</SchoolArrivalDate>

            <DailyRate/>

            <DestinationCode/>

            <Origin>NOWN</Origin>

            <PayReviewDate>15/10/2017</PayReviewDate>

            <LASchoolLevel/>

            <PostLevelDetails>

            <Payments>

            <PayRange>Teachers Upper</PayRange>

            <PayFramework/>

            <PayRangeMinimum/>

            <PayRangeMaximum/>

            <BasePay>40000</BasePay>

            <SafeguardedSalary>False</SafeguardedSalary>

            </Payments>

            <AdditionalPayments>

            <AdditionalPayment/>

            </AdditionalPayments>

            </PostLevelDetails>

            </ContractOrService>

            </ContractOrServiceGroup>

            </SchoolWorkforceMember>

            • 3. Re: xsl: variable name
              TomHays

              I think your error occurs because you have a set of nested loops.  The inner loop uses the same loop variable name "pos" as the outer loop.

               

                  <ContractOrService>

                   <xsl:for-each select="fm:PayrollNo/fm:DATA">

                        <xsl:variable name="pos" select="position()"/>

              ...

                     <AdditionalPayment>

                      <xsl:for-each select="fm:AdditionalPaymentType/fm:DATA">

                      <xsl:variable name="pos" select="position()"/>

              ...

                    </xsl:for-each>

                     </AdditionalPayment>

              ...

                   </xsl:for-each>

              </ContractOrService>

               

               

              The remedy should be to name the inner variable something distinct such as pos2 or perhaps name each variable to remind you of its loop pos_PayrollNo and pos_AdditionalPaymentType.

               

              -Tom

              1 of 1 people found this helpful
              • 4. Re: xsl: variable name
                beverly

                Sorry, this is not a raw XML export from FileMaker. (Use dummy data as needed.) Tom may be correct, and without the raw XML source, it is unknown where the "loops" do need to occur (xsl:for-each) in the XSLT.

                 

                Sent from miPhone

                • 5. Re: xsl: variable name
                  user19752

                  You can't use variable in loop, since the value can't be changed.

                  xsl:variable

                  2 of 2 people found this helpful
                  • 6. Re: xsl: variable name
                    beverly

                    I'm not sure what you mean. Within a given "scope" it is dynamic.

                     

                    ... xsl:for-each ...

                         ... xsl:variable name="pos" select="position()" / ...

                    ... /xsl:for-each ...

                     

                    The function position() is calculated differently each time through the loop.

                    beverly

                    • 7. Re: xsl: variable name
                      rrighini

                      HI all, thanks for the input.  I really have no great understanding of xsl.  The below is exactly what I want to achieve but my data doesn't export.  An employee can have a number contracts and then each contract can have a number of additional payments.  I wan -  the file to list the employees, with all their contracts listed under their name and then under each contract - each additional payment.  it will then loop back to contract number 2 and list the additional payments for that contract.  Once all contracts are listed It will go to the next employee.  My data is in three tables - one listing employees, one listing contracts and one listing additional payments.

                       

                      I hope this makes sense in my very incompetent way.  Many thanks for the support.

                      <EmployeeDetails>

                      .....

                      <ContractOrService>

                           <xsl:for-each select="fm:PayrollNo/fm:DATA">

                                <xsl:variable name="pos" select="position()"/>

                      ...

                             <AdditionalPayment>

                              <xsl:for-each select="fm:AdditionalPaymentType/fm:DATA">

                              <xsl:variable name="pos" select="position()"/>

                      ...

                            </xsl:for-each>

                             </AdditionalPayment>

                      ...

                           </xsl:for-each>

                      </ContractOrService>

                      </EmployeeDetails>

                      • 8. Re: xsl: variable name
                        beverly

                        Yes! Please Export a sample (bogus data) as XML without the XSLT, so that we may guide you properly.

                        You were thinking loop within loop and in a way that is close. I believe you want Muenchian Grouping

                        which is more complex.

                         

                        I will see if I can find  more examples using FM XML export with XSLT.

                        beverly

                         

                        Sent from miPhone

                        • 9. Re: xsl: variable name
                          beverly

                          P.S. The context of your XML export may also determine the grouping (and/or looping) that you do in your XSLT. examples:

                          1) from employees with related contracts (children) and with related payments (grandchildren)

                          2) from contracts with related (parent) employees and with related payments (children)

                          3) from payments with related contracts (parents) and related employees (grandparents)

                           

                          beverly

                          • 10. Re: xsl: variable name
                            beverly

                            This is just Customers and Orders (parent and child) example:

                            1) raw export

                            <?xml version="1.0" encoding="UTF-8" ?><FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult"><ERRORCODE>0</ERRORCODE><PRODUCT BUILD="05-13-2016" NAME="FileMaker" VERSION="ProAdvanced 14.0.6"/><DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="plain" NAME="Customers.fmp12" RECORDS="2" TIMEFORMAT="h:mm:ss a"/><METADATA>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="ID" TYPE="NUMBER"/>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Name" TYPE="TEXT"/>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="City" TYPE="TEXT"/>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Orders::OrderID" TYPE="NUMBER"/>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Orders::OrderDate" TYPE="DATE"/>

                            <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Orders::TotalAmt" TYPE="NUMBER"/></METADATA><RESULTSET FOUND="2">

                            <ROW MODID="1" RECORDID="22">

                            <COL><DATA>2</DATA></COL>

                            <COL><DATA>A Pealing Desserts</DATA></COL>

                            <COL><DATA>New York</DATA></COL>

                            <COL><DATA>ORD4</DATA></COL>

                            <COL><DATA>11-15-2002</DATA></COL>

                            <COL><DATA>115.00</DATA></COL></ROW>

                            <ROW MODID="1" RECORDID="24">

                            <COL><DATA>1</DATA></COL>

                            <COL><DATA>Herbson&apos;s Pices</DATA></COL>

                            <COL><DATA>Monterey</DATA></COL>

                            <COL><DATA>ORD2</DATA><DATA>ORD3</DATA></COL>

                            <COL><DATA>12-01-2002</DATA><DATA>01-06-2003</DATA></COL>

                            <COL><DATA>23.54</DATA><DATA>15.45</DATA></COL></ROW></RESULTSET></FMPXMLRESULT>

                            2) desired result

                            <?xml version="1.0" encoding="UTF-8"?>

                            <customers>

                              <customer ID="1">

                              <name>Monterey</name>

                              <city>Herbson's Pices</city>

                              <orders>

                              <order ID="ORD2">

                              <num>1</num>

                              <date>12-01-2002</date>

                              <amount>23.54</amount>

                              </order>

                              <order ID="ORD3">

                              <num>2</num>

                              <date>01-06-2003</date>

                              <amount>15.45</amount>

                              </order>

                              </orders>

                              </customer>

                              <customer ID="2">

                              <name>New York</name>

                              <city>A Pealing Desserts</city>

                              <orders>

                              <order ID="ORD4">

                              <num>1</num>

                              <date>11-15-2002</date>

                              <amount>115.00</amount>

                              </order>

                              </orders>

                              </customer>

                            </customers>

                            3) XSLT

                            <?xml version='1.0' encoding='UTF-8' ?>

                            <xsl:stylesheet version='1.0'

                              xmlns:xsl='http://www.w3.org/1999/XSL/Transform'

                              xmlns:fm="http://www.filemaker.com/fmpxmlresult"

                              exclude-result-prefixes="fm">

                              <xsl:output version='1.0' encoding='UTF-8' indent='yes' method='xml' />

                              <xsl:template match="/">

                              <customers>

                              <xsl:for-each select="fm:FMPXMLRESULT/fm:RESULTSET/fm:ROW">

                              <customer>

                              <xsl:attribute name="ID"><xsl:value-of select="./fm:COL[1]/fm:DATA" /></xsl:attribute>

                              <name><xsl:value-of select="./fm:COL[2]/fm:DATA" /></name>

                              <city><xsl:value-of select="./fm:COL[3]/fm:DATA" /></city>

                              <orders>

                              <xsl:for-each select="./fm:COL[4]/fm:DATA">

                              <xsl:variable name="recNum"><xsl:value-of select="position()" /></xsl:variable>

                              <order>

                              <xsl:attribute name="ID"><xsl:value-of select="." /></xsl:attribute>

                              <num><xsl:value-of select="position()" /></num>

                              <date><xsl:value-of select="../../fm:COL[5]/fm:DATA[position() = $recNum]" /></date>

                              <amount><xsl:value-of select="../../fm:COL[6]/fm:DATA[position() = $recNum]" /></amount>

                              </order>

                              </xsl:for-each>

                              </orders>

                              </customer>

                              </xsl:for-each>

                              </customers>

                              </xsl:template>

                            </xsl:stylesheet>

                            Notice the nested for-each and the usage of the variable (recNum) as position().

                             

                            To get the 3 levels, I would likely make the export from the middle level.

                            • 11. Re: xsl: variable name
                              beverly

                              Oops! I got the two columns (city & name) in the wrong export order, otherwise this is correct.

                              • 12. Re: xsl: variable name
                                beverly

                                This example used to be a download from the FMI site. It shows the Muenchian grouping and is provided "as is"

                                1 of 1 people found this helpful
                                • 13. Re: xsl: variable name
                                  user19752

                                  Hi, sorry it was my bad writing. I saw the variable is already defined out of (2nd) loop as the error message says. So I wrote it ambiguously since I wasn't sure without test it myself.

                                  • 14. Re: xsl: variable name
                                    beverly

                                    Using the same name for the variable within the two loops was the error. You and Tom are correct. I found other examples where I have nested loops and need the position() function. I used different names for the variables being set as a part of the for-each loops.

                                     

                                    Using template calls is another way to "loop" and often passes a "xsl:param", which becomes a variable much like the passing of script parameters. But the OP was not calling templates.