[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] FAQ answer doesn't seem to be working..


Subject: Re: [xsl] FAQ answer doesn't seem to be working..
From: Greg Faron <gfaron@xxxxxxxxxxxxxxxxxx>
Date: Mon, 11 Nov 2002 18:17:11 -0700

At 04:58 PM 11/11/2002, you wrote:
I am trying to take a basic XML file and turn it into a table. This table
should be two columns wide and as many rows long as required.

Following the instructions at:
http://www.dpawson.co.uk/xsl/sect2/N7450.html#d7256e205


With four hit's (my XML uses pet's) I get the following result:



Hit One Hit Two Hit Two Hit Three


Hit Four is never seen.. and as you can see hit two duplicates. I am using XMLSPY with the internal XSLT engine to work on this.


Is the FAQ in need of updating? Is XMLSPY not behaving properly? Did I copy it wrong?

First off, I'm surprised that you're seeing anything. Below are two typos that prevented me from transforming the files.
<TYPOS>


<xsl:template name="make_empty_cells">
        <xsl:with-param name="num" select="0"/>

This should be <xsl:param .../>, not "with-param".


        <xsl:if test="$num">
                <td>&#160;</td>
                <xsl:call-template name="make_empty_cells">
                        <xsl:with-param name="num - 1"/>

This should be <xsl:with-param name="num" select="$num - 1" />


                </xsl:call-template>
        </xsl:if>
</xsl:template>

</TYPOS>


The problem is during the initial selection, as seen here
<xsl:template match="pets">
<xsl:variable name="cols" select="3"/>
<xsl:variable name="all_pets" select="pet"/>
<xsl:for-each select="$all_pets[position() mod $cols = 1]">
<xsl:variable name="this_pet_pos" select="position()"/>
<xsl:variable name="current_row_pets" select="$all_pets[position() >= $this_pet_pos and $this_pet_pos + $cols > position()]"/>
...


When you set $this_pet_pos equal to position(), it is the position of the node within those nodes selected for the for-each, not those nodes assigned to $all_pets. This means that the values (no matter what $cols is equal to) will always be 1,2,3,...,count($all_pets)/$cols. What you want it to be is 1, $cols + 1, 2 * $cols + 1, ..., n * $cols + 1. Analyzing these two series, I can offer you a quick'n'dirty fix of assigning $this_pet_pos the value of
(position() - 1) * $cols + 1
This will transform the first (undesired) series into the second (desired) one. As for the FAQ, I haven't analyzed the other templates to see if they compensate for this position() issue. But if they don't compensate, I would say that they are incorrect in that regard.


A second place that your template fails you (and I don't know if you copied this part or not) is the assignment of $num_empty_cols. You state it should be equal to "$cols - $current_row_pets", but $current_row_pets is a nodeset, not a number. Change it to the assignment below and you will be fine.

<xsl:variable name="num_empty_cols" select="$cols - count($current_row_pets)"/>

Fix these four typos and you'll be done.


Greg Faron Integre Technical Publishing Co.



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords