Yvonne Garcia Posted November 4, 2004 Posted November 4, 2004 I've searched through the archive and can't quite find an answer to this issue. Any help would be appreciated. Here's the background info: FMPro 7 Advanced shared via CWP. One file, multiple tables. One table is Projects; another table is Personnel. I can get the Personnel related to Project to display, no problem using the following code: <xsl:when test="count(fmrs:relatedset[@table='Personnel']/fmrs:record)>0">
Martin Brändle Posted March 12, 2005 Posted March 12, 2005 The problem is that the context is changed when you change the XPath in the xsl:for-each statement. "Context" means the actual view or position of your XSLT transformation in your XML resultset tree. You can set e.g. the context with <xsl:template select="..."> or with <xsl:for-each select="..."> In your double-nested loop, you set the context to /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data within the inner loop. Therefore, within the inner loop, the XLST transform engine would see all the nodes and their subnodes conforming to this XPath. Now you try to access fmrs:field[@name='Personnel::id_prsn']/fmrs:data relative to this XPath in your <xsl:with-param statement, e.g. the absolute XPath would be /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data/fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Of course this can not work. One solution would be to change the relative path to something like ../../fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Depending on the number of cycles the loop has to do this can be bad for performance, because the XPath has to be evaluated in every cycle. Better is to save your person id in a variable before entering the loop, and use the variable then: <xsl:when test="count(fmrs:relatedset[@table='Personnel']/fmrs:record)>0"> <xsl:for-each select="fmrs:relatedset[@table='Personnel']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="person_id" select="fmrs:field[@name='Personnel::id_prsn']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prsnrecord"> <!-- use the variable here --> <xsl:with-param name="id_prsn" select="$person_id"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> <br/> Ok? Martin
Martin Brändle Posted March 12, 2005 Posted March 12, 2005 The problem is that the context is changed when you change the XPath in the xsl:for-each statement. "Context" means the actual view or position of your XSLT transformation in your XML resultset tree. You can set e.g. the context with <xsl:template select="..."> or with <xsl:for-each select="..."> In your double-nested loop, you set the context to /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data within the inner loop. Therefore, within the inner loop, the XLST transform engine would see all the nodes and their subnodes conforming to this XPath. Now you try to access fmrs:field[@name='Personnel::id_prsn']/fmrs:data relative to this XPath in your <xsl:with-param statement, e.g. the absolute XPath would be /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data/fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Of course this can not work. One solution would be to change the relative path to something like ../../fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Depending on the number of cycles the loop has to do this can be bad for performance, because the XPath has to be evaluated in every cycle. Better is to save your person id in a variable before entering the loop, and use the variable then: <xsl:when test="count(fmrs:relatedset[@table='Personnel']/fmrs:record)>0"> <xsl:for-each select="fmrs:relatedset[@table='Personnel']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="person_id" select="fmrs:field[@name='Personnel::id_prsn']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prsnrecord"> <!-- use the variable here --> <xsl:with-param name="id_prsn" select="$person_id"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> <br/> Ok? Martin
Martin Brändle Posted March 12, 2005 Posted March 12, 2005 The problem is that the context is changed when you change the XPath in the xsl:for-each statement. "Context" means the actual view or position of your XSLT transformation in your XML resultset tree. You can set e.g. the context with <xsl:template select="..."> or with <xsl:for-each select="..."> In your double-nested loop, you set the context to /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data within the inner loop. Therefore, within the inner loop, the XLST transform engine would see all the nodes and their subnodes conforming to this XPath. Now you try to access fmrs:field[@name='Personnel::id_prsn']/fmrs:data relative to this XPath in your <xsl:with-param statement, e.g. the absolute XPath would be /fmrs:fmresultset/fmrs:resultset/fmrs:relatedset[@table='Personnel']/fmrs:record/fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data/fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Of course this can not work. One solution would be to change the relative path to something like ../../fmrs:field[@name='Personnel::id_prsn']/fmrs:data . Depending on the number of cycles the loop has to do this can be bad for performance, because the XPath has to be evaluated in every cycle. Better is to save your person id in a variable before entering the loop, and use the variable then: <xsl:when test="count(fmrs:relatedset[@table='Personnel']/fmrs:record)>0"> <xsl:for-each select="fmrs:relatedset[@table='Personnel']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="person_id" select="fmrs:field[@name='Personnel::id_prsn']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Personnel::x_prsn_LastName_FirstName']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prsnrecord"> <!-- use the variable here --> <xsl:with-param name="id_prsn" select="$person_id"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> <br/> Ok? Martin
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 Martin, Thank you for the great explanation and the code. That worked well with the Personnel situation I outlined. After reading your post, I thought I understood the issue with "Context" so I tried my hand at another similar situation. However, I wound up with the same problem I had with the Personnel situation. It looks like a link but the variable isn't being passed. Can you point out where my thinking/coding is flawed? Here's the code I created based on the personnel example you shared with me: <td align="left" valign="top"><br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="whynot" select="fmrs:field[@name='Project_Open::id_master']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <!-- use the variable here --> <xsl:with-param name="id_master" select="$whynot"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> </xsl:for-each> </xsl:for-each> </td> It DOES work if I go back to my clunky workaround of linking on some static text instead of the dynamic field: <tr> <td> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <xsl:value-of select="fmxslt:break_encode(.)" disable-output-escaping="yes" /><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> <td align="left"> <br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::id_master']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <xsl:with-param name="id_master" select="."/> </xsl:call-template> </xsl:attribute> (view) </a><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> </tr> Thanks in advance for the help and the education. - Yvonne
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 Martin, Thank you for the great explanation and the code. That worked well with the Personnel situation I outlined. After reading your post, I thought I understood the issue with "Context" so I tried my hand at another similar situation. However, I wound up with the same problem I had with the Personnel situation. It looks like a link but the variable isn't being passed. Can you point out where my thinking/coding is flawed? Here's the code I created based on the personnel example you shared with me: <td align="left" valign="top"><br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="whynot" select="fmrs:field[@name='Project_Open::id_master']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <!-- use the variable here --> <xsl:with-param name="id_master" select="$whynot"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> </xsl:for-each> </xsl:for-each> </td> It DOES work if I go back to my clunky workaround of linking on some static text instead of the dynamic field: <tr> <td> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <xsl:value-of select="fmxslt:break_encode(.)" disable-output-escaping="yes" /><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> <td align="left"> <br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::id_master']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <xsl:with-param name="id_master" select="."/> </xsl:call-template> </xsl:attribute> (view) </a><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> </tr> Thanks in advance for the help and the education. - Yvonne
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 Martin, Thank you for the great explanation and the code. That worked well with the Personnel situation I outlined. After reading your post, I thought I understood the issue with "Context" so I tried my hand at another similar situation. However, I wound up with the same problem I had with the Personnel situation. It looks like a link but the variable isn't being passed. Can you point out where my thinking/coding is flawed? Here's the code I created based on the personnel example you shared with me: <td align="left" valign="top"><br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <!-- variable definition here --> <xsl:variable name="whynot" select="fmrs:field[@name='Project_Open::id_master']/fmrs:data[1]"/> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/></xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <!-- use the variable here --> <xsl:with-param name="id_master" select="$whynot"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </a> </xsl:for-each> </xsl:for-each> </td> It DOES work if I go back to my clunky workaround of linking on some static text instead of the dynamic field: <tr> <td> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::prj_title']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <xsl:value-of select="fmxslt:break_encode(.)" disable-output-escaping="yes" /><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> <td align="left"> <br/> <xsl:for-each select="fmrs:relatedset[@table='Project_Open']/fmrs:record"> <xsl:for-each select="fmrs:field[@name='Project_Open::id_master']/fmrs:data"> <xsl:if test="position() != 1"><br/> </xsl:if> <a> <xsl:attribute name="href"> <xsl:call-template name="link-prjrecord-pi"> <xsl:with-param name="id_master" select="."/> </xsl:call-template> </xsl:attribute> (view) </a><br/> <xsl:if test=". = ''"> <xsl:text disable-output-escaping="yes"> </xsl:text> </xsl:if> </xsl:for-each> </xsl:for-each> <br/> </td> </tr> Thanks in advance for the help and the education. - Yvonne
Martin Brändle Posted March 14, 2005 Posted March 14, 2005 Hmm, the upper code looks ok IMHO. Might it be that the id_master field is missing in Project_Open portal on the layout you use? Add a line <textarea rows="10" cols="80"><xsl:copy-of select="$whynot"/></textarea> after your variable definition in order to debug the variable (to show its contents). I also noticed that the XML resultset tree depends on the order in which one has placed the fields on the layout. E.g. if you place first fields of the main table, than of the related table, than again of the main table, than again of the related table, your fmrs:relatedset part is split into two parts, and the XSLT might have problems to address the parts correctly. The best is then to rebuild the layout. Martin
Martin Brändle Posted March 14, 2005 Posted March 14, 2005 Hmm, the upper code looks ok IMHO. Might it be that the id_master field is missing in Project_Open portal on the layout you use? Add a line <textarea rows="10" cols="80"><xsl:copy-of select="$whynot"/></textarea> after your variable definition in order to debug the variable (to show its contents). I also noticed that the XML resultset tree depends on the order in which one has placed the fields on the layout. E.g. if you place first fields of the main table, than of the related table, than again of the main table, than again of the related table, your fmrs:relatedset part is split into two parts, and the XSLT might have problems to address the parts correctly. The best is then to rebuild the layout. Martin
Martin Brändle Posted March 14, 2005 Posted March 14, 2005 Hmm, the upper code looks ok IMHO. Might it be that the id_master field is missing in Project_Open portal on the layout you use? Add a line <textarea rows="10" cols="80"><xsl:copy-of select="$whynot"/></textarea> after your variable definition in order to debug the variable (to show its contents). I also noticed that the XML resultset tree depends on the order in which one has placed the fields on the layout. E.g. if you place first fields of the main table, than of the related table, than again of the main table, than again of the related table, your fmrs:relatedset part is split into two parts, and the XSLT might have problems to address the parts correctly. The best is then to rebuild the layout. Martin
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 My first thought was that the id_master field was missing from the portal as well. But, alas, it wasn't. I rebuilt the layout and that did the trick! Thank you very much, Martin.
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 My first thought was that the id_master field was missing from the portal as well. But, alas, it wasn't. I rebuilt the layout and that did the trick! Thank you very much, Martin.
Yvonne Garcia Posted March 14, 2005 Author Posted March 14, 2005 My first thought was that the id_master field was missing from the portal as well. But, alas, it wasn't. I rebuilt the layout and that did the trick! Thank you very much, Martin.
Recommended Posts
This topic is 7194 days old. Please don't post here. Open a new topic instead.
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now