Subject: Re: [xsl] Table styling From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Thu, 14 Feb 2002 15:29:29 +0000 |
Hi Arup, > As I am rendering table of three colomns,my problem is when I am > looping for services to create new row It creates first row > correctly but for second row instead of going to position 4 of > services it goes to second position and so on . Can any one suggest > where I am making mistake or correction in Xsl or in code. The problem is at the point where you select the 'current_row_services'. Currently, the code for creating the content of the table is as follows: <xsl:for-each select="$all_services[position() mod $cols = 1]"> <xsl:variable name="this_services_pos" select="position()"/> <xsl:variable name="current_row_services" select="$all_services[position() >= $this_services_pos and position() < $this_services_pos + $cols]" /> <!-- go generate the 2 table rows for this one data row --> <xsl:call-template name="make_table_rows"> <xsl:with-param name="cols" select="$cols"/> <xsl:with-param name="current_row_services" select="$current_row_services"/> </xsl:call-template> </xsl:for-each> The xsl:for-each here selects the services numbered 1, 4, 7 and so on in the whole list of services. This filtered list of services becomes the current node list within the xsl:for-each. The first node processed (whose position is 1 in the xsl:for-each) is the first of all the services; the second node processed (whose position is 2 in the xsl:for-each) is the fourth of all the services; the third node processed (whose position is 3 in the xsl:for-each) is the seventh of all the services and so on. In other words, the $this_services_pos variable takes the values 1, 2, 3 and so on and *not* 1, 4, 7 etc. Which is why the code that you have isn't working. But rather than show you how to get what you have working, I'll show you a different, and more efficient method, to work out which services elements should be passed to the make_table_rows template. As we've seen, with your xsl:for-each as it stands, you're getting the first, fourth, seventh and so on services element within the document. You know that these services elements are the first services element to be shown within the row. The other services elements are siblings of these. In fact, the other services elements that you want to display within the row are the two following siblings of the services element that you're on. So rather than accessing the other services elements by index, you can step from these selected services elements to their following siblings through the following-siblings axis, as follows: <xsl:for-each select="$all_services[position() mod $cols = 1]"> <xsl:variable name="current_row_services" select=". | following-sibling::services[position() < $cols]" /> <!-- go generate the 2 table rows for this one data row --> <xsl:call-template name="make_table_rows"> <xsl:with-param name="cols" select="$cols"/> <xsl:with-param name="current_row_services" select="$current_row_services"/> </xsl:call-template> </xsl:for-each> This is more efficient because the processor will only have to visit three nodes to create the list of nodes that you're after, rather than trawling through the entire list of services to find those with the correct position. --- These grouping by position problems are slightly assisted with the xsl:for-each-group element proposed for XSLT 2.0. An equivalent to the above code, in XSLT 2.0, would be: <xsl:for-each-group select="$all_services" group-starting-with="position() mod $cols = 1"> <xsl:variable name="current_row_services" select="current-group()" /> <!-- go generate the 2 table rows for this one data row --> <xsl:call-template name="make_table_rows"> <xsl:with-param name="cols" select="$cols"/> <xsl:with-param name="current_row_services" select="$current_row_services"/> </xsl:call-template> </xsl:for-each> It's not *extremely* user-friendly, given the number of times people want to group by position. I wonder whether a group-number would be more helpful - an attribute value template perhaps: <xsl:for-each-group select="$all_services" group-number="{$cols}"> <xsl:variable name="current_row_services" select="current-group()" /> <!-- go generate the 2 table rows for this one data row --> <xsl:call-template name="make_table_rows"> <xsl:with-param name="cols" select="$cols"/> <xsl:with-param name="current_row_services" select="$current_row_services"/> </xsl:call-template> </xsl:for-each> Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Table styling, ajay sinha | Thread | [xsl] xsl:include with plain text i, Peter Davis |
[xsl] position() returning incorrec, jon wa | Date | RE: [xsl] how to select the same at, Andrew Welch |
Month |