xsl-list
[Top] [All Lists]

Re: xslt 2.0 challenge

2004-04-08 09:08:10
Hi Andrew,

The steps involved are:

1.  Find the corresponding start and end <colspecs> based on @namest and
@nameend
2.  Sum the @colwidth values for the <colspecs> between (and including)
the columns found in step1
3.  Divide that value by the sum of all colwidths for that group
(siblings) and add on a % symbol

Here's another XSLT 2.0 solution. This one uses a function to do the
summing of column widths, and <xsl:for-each> rather than a for
expression (pah!). I use the new >> operator to identify the colspecs
between two others. I also take advantage of the XSLT 1.0
format-number() facility of including a % in the format pattern in
order to get a number formatted as a percentage.

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:xs="http://www.w3.org/2001/XMLSchema";
                xmlns:my="http://www.jenitennison.com/";>

<xsl:function name="my:sum-widths" as="xs:integer">
  <xsl:param name="colspecs" as="element()+" />
  <xsl:variable name="widths" as="xs:integer+">
    <xsl:for-each select="$colspecs">
      <xsl:sequence select="xs:integer(translate(@colwidth, 'm', ''))" />
    </xsl:for-each>
  </xsl:variable>
  <xsl:sequence select="sum($widths)" />
</xsl:function>

<xsl:template match="spanspec">
  <xsl:variable name="all-colspecs" as="element()+"
    select="ancestor::table//colspec" />
  <xsl:variable name="first-colspec" as="element()"
    select="$all-colspecs[(_at_)colname = current()/@namest]" />
  <xsl:variable name="last-colspec" as="element()"
    select="$all-colspecs[(_at_)colname = current()/@nameend]" />
  <xsl:variable name="sibling-colspecs" as="element()+"
    select="$first-colspec/../colspec" />
  <xsl:variable name="span-colspecs" as="element()+"
    select="$first-colspec |
            $sibling-colspecs[$last-colspec >> . and . >> $first-colspec] |
            $last-colspec" />
  <xsl:value-of select="format-number(my:sum-widths($span-colspecs) div
                                      my:sum-widths($sibling-colspecs),
                                      '#0.00%')" />
</xsl:template>

</xsl:stylesheet>

Not all the variable declarations are necessary of course, though
declaring the types of the variables helped me debug the code. The
element node tests would be "element(colspec, *)" rather than just
"element()", but I wanted a solution that worked in Saxon 7.

Cheers,

Jeni

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



<Prev in Thread] Current Thread [Next in Thread>