Reputation: 3138
I have a following xslt code :
<xsl:template match="table_terms_and_abbr">
<informaltable frame='none' colsep='none' rowsep='none'>
<tgroup cols='2' align='left'>
<colspec colnum="1" colwidth='1*'/>
<colspec colnum="2" colwidth='1*'/>
<xsl:apply-templates/>
</tgroup>
</informaltable>
</xsl:template>
and the following xml that it's processing :
<table_terms_and_abbr>
<tblrow_hdr>Name ,, Description</tblrow_hdr>
<tbody>
<tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
...
</tbody>
</table_terms_and_abbr>
Now i want to improve the xslt by moving following lines inside the table_terms_and_abbr
:
<tblrow_hdr>Name ,, Description</tblrow_hdr>
<tbody>
</tbody>
So i will have something like :
<xsl:template match="table_terms_and_abbr">
<informaltable frame='none' colsep='none' rowsep='none'>
<tgroup cols='2' align='left'>
<colspec colnum="1" colwidth='1*'/>
<colspec colnum="2" colwidth='1*'/>
<xsl:call-template name="tblrow_hdr">
BOT ,, &j_bot; * ???? *
</xsl:call-template>
<tbody>
<xsl:apply-templates/>
</tbody>
</tgroup>
</informaltable>
</xsl:template>
The line marked with * ???? * does not work. I using saxon9 (xslt 2.0 stylesheet) on linux platform and got this error:
XTSE0010: No character data is allowed within xsl:call-template
I know how to pass the attributes to the template i.e:
<xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>
but how to pass free text ?
The idea is move to the template all static data and in xml only use variable data i.e
<table_terms_and_abbr>
<tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
...
</table_terms_and_abbr>
More Info
My requirement was to create a simplified syntax for defining repeatable tables for our DocBook documentation. For that i created a general named template tblrow
that will split the line delimited by ",," to separate entities and will create a list of entries in the table row.
Each entry can be a simple string, an ENTITY or another template.
Since the parameter numbers are undefined (the tables can have different number of cells) i can't use a standard parameters for the templates and used delimited string. If i want to have one of the table entries to contain a link to some place in the document i can't use the parameters again since i can't pass xref template as a parameter.
The main reason not to change the tblrow
template is that it's working :) and it's kind of complex. It's took me ages to achieve this and I'm not completely understand how it's working :).
Now on top of this i have a few variables that can control the displayed output like tblrow_hdr
that will underline and bold the text in each entry. Since tblrow_hdr
is common for all table_terms_and_abbr
tables it just sounds logical to me not having this in xml rather put the call to the tblrow_hdr
inside the table_terms_and_abbr
template and here i stuck.
Upvotes: 2
Views: 1818
Reputation: 243579
> Since the parameter numbers are > undefined (the tables can have > different number of cells) i can't use > a standard parameters for the > templates and used delimited string.
Actually, this is not so.
Here is an example of an
<xsl:with-param/>, the body of which is a node-set that may consist of different number of elements on different calls:
<xsl:template match="/"> <xsl:variable name="vrtfTParams"> <p>xxx</p> <p>yyy</p> <p>zzz</p> </xsl:variable> <xsl:call-template name="makeTable"> <xsl:with-param name="pTParams" select="msxsl:node-set($vrtfTParams)/*"/> </xsl:call-template> </xsl:template>
The "makeTable" template can be as simple as this:
<xsl:template name="makeTable"> <xsl:param name="pTParams"/> <table> <tr> <xsl:for-each select="$pTParams"> <td> <xsl:value-of select="."/> </td> </xsl:for-each> </tr> </table> </xsl:template>
The msxsl:node-set() extension function can be used with a Microsoft XSLT processor. Most other processors support the exslt:node-set() extension function (Microsoft's .Net XSLT processor XslCompiledTransform also supports it).
In case the contents of $vrtfTParams is not dynamically generated (as is the case in this example), no xxx:node-set() function is necessary, because the contents of the <xsl:variable> can be passed like this:
<xsl:with-param name="pTParams" select="document('')/*/xsl:variable[name()=vrtfTParams)/*"/>
Here $vrtfTParams must be globally defined (a child of <xsl:template/>).
In XSLT 2.0 (and XPath 2.0) there is no RTF type and no xxx:node-set() extension function is needed at all.
Hope this helped.
Cheers,
Dimitre Novatchev
Upvotes: 1
Reputation: 243579
You can pass the additional string data as a parameter:
<xsl:with-param name="pNeededText" select="'--123Abc'"/>
and in the called template define this parameter:
<xsl:param name="pNeededText" as="xs:string">
Or, you could define a global <xsl:variable/>
or <xsl:param/>
and reference it directly in the called template.
Upvotes: 1
Reputation: 54544
I know how to pass the attributes to the template i.e:
<xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>
but how to pass free text ?
Pass the text as the content of an xsl:with-param
element.
XSL Transformations 11.6 Passing Parameters to Templates
<xsl:with-param
name = qname
select = expression>
<!-- Content: template -->
</xsl:with-param>
Parameters are passed to templates using the xsl:with-param
element. The required name
attribute specifies the name of the parameter (the variable the value of whose binding is to be replaced). The value of the name attribute is a QName, which is expanded as described in [2.4 Qualified Names]. 'xsl:with-param' is allowed within both xsl:call-template
and xsl:apply-templates
. The value of the parameter is specified in the same way as for xsl:variable
and xsl:param
. The current node and current node list used for computing the value specified by xsl:with-param
element is the same as that used for the xsl:apply-templates
or xsl:call-template
element within which it occurs. It is not an error to pass a parameter x to a template that does not have an xsl:param
element for x; the parameter is simply ignored.
This example defines a named template for a numbered-block with an argument to control the format of the number.
<xsl:template name="numbered-block">
<xsl:param name="format">1. </xsl:param>
<fo:block>
<xsl:number format="{$format}"/>
<xsl:apply-templates/>
</fo:block>
<xsl:template match="ol//ol/li">
<xsl:call-template name="numbered-block">
<xsl:with-param name="format">a. </xsl:with-param>
</xsl:call-template>
</xsl:template>
Upvotes: 3