RE: [xsl] Transformation for FO table widths

Subject: RE: [xsl] Transformation for FO table widths
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Mon, 29 Apr 2002 20:01:05 +0100
>
> I want to use WIDTH attributes only on the *first* row in a
> table, ... The
> problems seem to start when I sum up percent values and pixel
> values in two
> node-sets:
>
>   <!-- Match the first row in any table -->
>   <xsl:template match="TR[1]">
>     <fo:table-row>
>       <xsl:if test="TH/@WIDTH | TD/@WIDTH">
>         <!-- Get @WIDTH-nodes with percent values -->
>         <xsl:variable name="percent-nodes">
>           <xsl:value-of select="TH[contains(@WIDTH, '%')] |
>                                 TD[contains(@WIDTH, '%')]"/>
>         </xsl:variable>
>
You don't want a result tree fragment here, you want a node-set. Write:

<xsl:variable name="percent-nodes"
              select="TH[contains(@WIDTH, '%')] |
>                     TD[contains(@WIDTH, '%')]"/>

What I do
> next is to
> sum up these values, like this:
>
>   <!-- Sum up percent values -->
>   <xsl:variable name="percent-sum"
>     select="sum(number(substring-before($percent-nodes, '%')))"/>

Summing over a computed expression is not easy in XSLT 1.0. There are
various extension functions that do it in various products; or you can
create an RTF with nodes that contain the computed numbers and use sum()
over the nodes in that RTF, which requires the node-set extension. The pure
way is to use recursion; and no doubt Dimitre has an off-the-shelf dynamic
template that does it. What you can't do is what you're trying to do above:
the sum() function expects a node-set, but number() returns a number.

In XPath 2.0 (implemented in Saxon 7.0) you can write

select="sum(for $i in $percent-nodes return
             number(substring-before($i, '%')))"

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx


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


Current Thread