Subject: RE: xslt 2.0 challenge
From: "Andrew Welch" <AWelch@xxxxxxxxxxxxxxx>
Date: Tue, 13 Apr 2004 09:01:38 +0100
|
Thanks Jeni,
This is the fastest solution so far (in my non-scientific tests), and
gives me plenty of new things to learn :)
cheers
andrew
> 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[@colname = current()/@namest]" />
> <xsl:variable name="last-colspec" as="element()"
> select="$all-colspecs[@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/
|