This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: math get maximum and subtract 1


Hi Sascha,

>> Note that this only works because your DESCRIPTION_ITEMs are sorted by
>> column and then by row. If they're sorted in some other way, or aren't
>> actually sorted at all, then we need to try another method.
>
> remember that topic? Well, actually that IS what we have right
> now... Our client has changed it's export and the description_items
> aren't sorted at all.

Can you get them to change it back again? Or get them to add the
counts of rows and columns to the DESCRIPTION_TABLE element? Of course
it's not impossible to work out the number of rows and columns from
the unsorted source, but it's a bit of a pain when these are things
that are probably fairly easy for the client to supply.

If your tables are small or you're not particularly worried about
speed, you can find the number of columns by looking at the value of
the col attribute for the first DESCRIPTION_ITEM for which there is no
other DESCRIPTION_ITEM with a larger value for its col attribute:

  DESCRIPTION_ITEM[not(../DESCRIPTION_ITEM/@col > @col)][1]/@col

If that's too slow, you could try sorting the DESCRIPTION_ITEMs by the
value of their col attribute in descending order, and then pick the
value of the col attribute on the first:

  <xsl:for-each select="DESCRIPTION_ITEM">
    <xsl:sort select="@col" data-type="number" order="descending" />
    <xsl:if test="position() = 1">
      <xsl:value-of select="@col" />
    </xsl:if>
  </xsl:for-each>

If that's still too slow, you should use a recursive solution that
steps through the DESCRIPTION_ITEM elements one by one keeping track
of the maximum at each step:

<xsl:template name="countCols">
  <xsl:param name="items" select="DESCRIPTION_ITEM" />
  <xsl:param name="max" select="0" />
  <xsl:choose>
    <xsl:when test="$items">
      <xsl:call-template name="countCols">
        <xsl:with-param name="items"
                        select="$items[position() > 1]" />
        <xsl:with-param name="max">
          <xsl:choose>
            <xsl:when test="$max > $items[1]/@col">
              <xsl:value-of select="$max" />
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$items[1]/@col" />
            </xsl:otherwise>
          </xsl:choose>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$max" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

You'll probably be able to speed up all of these solutions by only
looking at the DESCRIPTION_ITEM elements whose row attribute has the
value '0' (assuming that each row has the same number of columns).

Working out the number of rows can be done in exactly the same way.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]