Well, I figured out a non-xsl:number way to do it, but there are a few notes.
Looking carefully at the XSLT1.0 spec for xsl:number, I figured out what the level="any" option really means. To wit, "the union of the members of the preceding and ancestor-or-self axes". The following solution does not take into account the count and from options of xsl:number. And it wires-in the node type "C". If node() is used instead of C, then all nodes, including text nodes, are counted. There might be some way in XPath to match only the current node type. With a test case of 1028 nodes the Xalan-J-2.2.0 run times are about the same (4-5 secs PIII/600EB, W2K, JDK1.3.1/Ant 1.4.1). As for xsl:number, I think grouping-separator="" should not give a "String index out of range: 0" exception. However, grouping-size="0" appears to serve the purpose of suppressing the separator, although this may be a Xalan feature -- XSLT1.0 doesn't seem to specify this. I kind of enjoy doing this sleuthing to learn the subtelties of Xalan and XSLT. P.S. On Xalan-J-2.0.1 this solution runs 7 secs compared to 4 secs for my test case of 1028 nodes. I guess the xsl:number code may optimize the union of the two axes. Oh well. ================================ <!-- Xalan-J-2.0.1 and Xalan-J-2.2.0 --> <!-- serial number for each C node in document order --> <xsl:template match="C"> <xsl:call-template name="foo"> <!-- ALSO WORKS <xsl:with-param name="bar"><xsl:number level="any" grouping-separator="," grouping-size="0"/></xsl:with-param> --> <xsl:with-param name="bar" select="count(preceding::C | ancestor-or-self::C)"/> </xsl:call-template> </xsl:template> <xsl:template name="foo"> <xsl:param name="bar"/> <xsl:value-of select="$bar*1000"/>, </xsl:template> =====================================
