xsl-list
[Top] [All Lists]

RE: how to capture a value returned by a template call into a variable

2003-01-09 03:26:42
Hi, Jeni and Edwards,

Thanks so much for your help and answers. They are tremendously helpful!

Thanks,

Anthony


-----Original Message-----
From: Jeni Tennison [mailto:jeni(_at_)jenitennison(_dot_)com]
Sent: Thursday, January 09, 2003 5:51 PM
To: Anthony Kong
Cc: 'xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com'
Subject: Re: [xsl] how to capture a value returned by a template call
into a variable


Hi Anthony,

I would like to modularise some common code as a function. But in
XSLT 1.0 there is no function facility. My common code involved is
to tranlate a DB type into a java type. That is what i have done:

 <xsl:variable name="java_type">
        <xsl:call-template name="translate_type">
            <xsl:with-param name="db_type" select="@jdbc-type"/>
        </xsl:call-template>
    </xsl:variable>

I intended (wish, actually :-) to capture the result into variable
"java_type". However it failed.

[later...]
The template is as such:

 <xsl:template name="translate_type" >
     <xsl:param name="db_type" />
     <xsl:choose >
         <xsl:when test="$db_type='CHAR'">String</xsl:when>
         <xsl:when test="$db_type='VARCHAR'">String</xsl:when>
[snip]
    </xsl:choose>
 </xsl:template>

I don't know why your template call failed. Perhaps the current node
at the point you set your variable is not what you think it is -- you
should check whether the correct value is being passed through as the
$db_type parameter.

In this particular case, a better approach would be to create an XML
lookup table, say in db_types.xml, which looked like:

<db_types>
  <db_type java="String">CHAR</db_type>
  <db_type java="String">VARCHAR</db_type>
  ...
</db_types>

You could then look up the value that you wanted to translate using a
single XPath as follows:

 <xsl:variable name="db_types"
   select="document('db_types.xml')/db_types/db_type" />
 <xsl:variable name="java_type"
   select="$db_types[. = current()/@jdbc-type]/@java" />

In other words, find the <db_type> element from db_types.xml whose
value is the same as the jdbc-type attribute on the current node, and
then find the value of its java attribute.

But to answer your more general question, you're correct that in
unextended XSLT 1.0 you have to call templates to perform functions
and that sometimes this can lead to verbose and ungainly code.
However, most XSLT processors have a mechanism for defining extension
functions. Several support EXSLT's func:function/func:result elements,
which enable you to do:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:func="http://exslt.org/functions";
                xmlns:db="http://www.example.org/db";
                extension-element-prefixes="func db">

<func:function name="db:translate_type">
  <xsl:param name="db_type" />
  <func:result>
    <xsl:choose>
      <xsl:when test="$db_type='CHAR'">String</xsl:when>
      <xsl:when test="$db_type='VARCHAR'">String</xsl:when>
      ...
    </xsl:choose>
  </func:result>
</func:function>

...
  <xsl:variable name="java_type"
                select="db:translate_type(@jdbc-type)" />
...

</xsl:stylesheet>

See http://www.exslt.org/func/elements/function/index.html for
details.

XSLT 2.0 will support user-defined functions written using XSLT with
xsl:function/xsl:result elements that work in roughly the same way as
func:function/func:result. See
http://www.w3.org/TR/xslt20/#stylesheet-functions.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

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



<Prev in Thread] Current Thread [Next in Thread>