Barry,
Two problems here. One is the one you asked about ... how you pass a node
to a named template as a parameter. The other is that either you haven't
quite understood the notion of a "context node" (a critical notion in
XSLT), or you haven't explained/described your problem (since it doesn't
match your approach).
The second problem is the deeper one, and if we address it the first one
will just go away.
At 04:38 AM 9/18/2003, you wrote:
so now i heard i could use nested template, like
-------------------------------------------------
<xsl:template match="//Row">
<fo:table-row>
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<xsl:value-of select="TT"/>
</fo:block>
</fo:table-cell>
<xsl:call-template name="cell"/>
</fo:table-row>
</xsl:template>
Correct. Calling the "cell" template with no parameters, it nonetheless
takes the context node as its context node. So if in your source data you have
<Row>
<aaa>Total</aaa>
<TdD>null</TdD>
<NA>45678</NA>
<FR>45644</FR>
</Row>
when you evaluate this (or any) Row, the template above gives you an
fo:table-row containing a cell with the value of the Row's TT child (hey!
you don't have any! so what do you want in that cell?), followed by
whatever the "cell" template does, with the matched node of the calling
template (the row) as its context node.
But when you call the "cell" template
<xsl:template name="cell">
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<xsl:variable name="cell" select="//Row/[*]"/> <---------------Here's
where i think i go wrong, how do i select the nodes
Right -- you're stuck. How, from a "Row" (the context node) do you pick
each one of the nodes in turn?
Actually, it can be done, wrapping it all in a for-each -- but this
technique isn't actually the most efficient way XSLT offers to address your
requirement.
Better would be not to pick these nodes up from the Row, but to *change*
the context node to each of these. This is very simply done by applying its
own template to each them, using a match. Then the context node changes by
itself:
<xsl:template match="TdD | NA | FR">
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<!-- we don't need to bind any nodes to the variable: rather, the
node we're interested in is whatever node we matched:
our context node -->
<xsl:choose>
<xsl:when test="not(self::node() = 'null')">
<xsl:value-of select="self::node()"/>
</xsl:when>
</xsl:choose>
</fo:block>
</fo:table-cell>
</xsl:template>
Which could be simplified and abbreviated to
<xsl:template match="TdD | NA | FR">
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<xsl:value-of select="self::node()[not(.='null')]"/>
</fo:block>
</fo:table-cell>
</xsl:template>
But to call this template for each of those nodes, we need to change our
calling template:
<xsl:template match="Row">
<fo:table-row>
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<xsl:value-of select="child::TT"/>
<!-- whatever that is... I think you mean select="aaa" -->
</fo:block>
</fo:table-cell>
<xsl:apply-templates name="child::TdD | child::NA | child::FR"/>
</fo:table-row>
</xsl:template>
"TdD | NA | FR" is short for "child::TdD | child::NA | child::FR", just to
be perfectly clear.
Barry, I suggest you might spend a bit of time researching the XSLT
processing model. Basically an XSLT processor starts by matching a root
node, and is set up by default to traverse down through the tree
(depth-first traversal in "document order"), matching templates as it goes.
Each of these templates has the opportunity to create nodes in the output,
nodes which in each case end up "wrapping" or "containing" the nodes
generated by templates "lower" in the tree (its children and descendants).
You simply need to match at two levels -- the row (which generates a row,
surprisingly) and the item within the row (which generates a cell). The
XSLT Processor can take care of this traversal for you, if you let it.
Note that although this is "natural", there are times when other
complications -- such as, one might want two of your three nodes grouped
together in a single cell -- make it very useful to do it with a named
template after all. Such as
<xsl:template match="Row">
<fo:table-row>
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<fo:block>
<xsl:value-of select="child::TT"/>
<!-- whatever that is... I think you mean select="aaa" -->
</fo:block>
</fo:table-cell>
<xsl:call-template name="cell">
<xsl:with-param name="contents" select="TdD | NA"/>
</xsl:call-template>
<xsl:call-template name="cell">
<xsl:with-param name="contents" select="FR"/>
</xsl:call-template>
</fo:table-row>
</xsl:template>
<xsl:template name="cell">
<xsl:param name="contents" select="."/>
<xsl:variable name="string-value">
<xsl:apply-templates select="contents"/>
</xsl:variable>
<fo:table-cell border="solid black 1 px" border-collapse="collapse">
<xsl:for-each select="$contents[not(.='null')">
<fo:block>
<xsl:value-of select="."/>
</fo:block>
</xsl:for-each>
</fo:table-cell>
</xsl:template>
I hope this is helpful. If it's confusing, study up on templates and the
processing model.
Cheers,
Wendell
Any more suggestions.
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
___&&__&_&___&_&__&&&__&_&__&__&&____&&_&___&__&_&&_____&__&__&&_____&_&&_
"Thus I make my own use of the telegraph, without consulting
the directors, like the sparrows, which I perceive use it
extensively for a perch." -- Thoreau
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list