xsl-list
[Top] [All Lists]

Re: Data types and xsl:sequence

2005-01-25 16:24:54
Just one missing improvement -- it is again about typing.

Following the same approach for specifying types and letting
type-checking catch errors that otherwise might go unnoticed, it is
best to specify the (return) type of an xsl:function, too.

Therefore, we'll add type to:

<xsl:function name="t:pad">

and finally have:

     <xsl:function name="t:pad" as="xs:string">


Cheers,
Dimitre Novatchev


On Wed, 26 Jan 2005 07:51:27 +1100, Dimitre Novatchev
<dnovatchev(_at_)gmail(_dot_)com> wrote:
Just specify the types of the parameters -- types help eliminate
exactly such problems:

 <xsl:param name="char" as="xs:string" />

When calling the template pass '0' insted of 0, otherwise you will
(correctly!) get a type error.

So, with minimal changes the transformation becomes something like this:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema";

<xsl:output method="text"/>

<xsl:template match="/">
  Results: '<xsl:text/>
  <xsl:call-template name="pad-number">
    <xsl:with-param name="max" select="5"/>
    <xsl:with-param name="char" select="'0'"/>
  </xsl:call-template>'
</xsl:template>

<xsl:template name="pad-number">

 <xsl:param name="max" />
 <xsl:param name="char" as="xs:string" />

 <xsl:sequence select=
    "string-join((for $i in 1 to xs:integer($max)
                   return $char
                  ),
                  ''
                 )"/>
</xsl:template>
</xsl:stylesheet>

and the result is as expected:

Results: '00000'

The code will be better written as an xsl:function and specifying the
types of all parameters involved, so that type errors will not go
unnoticed:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:t="http://myURL/test";

<xsl:output method="text"/>

<xsl:template match="/">
  Results: '<xsl:value-of select="t:pad(5, '0')"/>'
</xsl:template>

<xsl:function name="t:pad">
 <xsl:param name="max" as="xs:integer" />
 <xsl:param name="char" as="xs:string" />

 <xsl:sequence select=
    "string-join((for $i in 1 to $max
                          return $char
                         ),
                        ''
                       )"/>
</xsl:function>
</xsl:stylesheet>

Note how the code is actually simplified:

 1. No need to have a special template for pad-number and pad-character

 2. No need to construct an xs:integer from $max

 3. Benefits from type checking so that if inappropriately-typed
arguments are passed this will not go unnoticed and will be
immediately raised as error

 4. Referencing the function is much more compact than the 4 lines
needed for xsl:call-template.

 5. More importantly, the function can be used immediately in any
XPath expression at any place where the syntax rules allow this.

Cheers,
Dimitre Novatchev.


On Mon, 24 Jan 2005 16:17:41 -0500, Jim Neff 
<jneff(_at_)blockvision(_dot_)com> wrote:
Greetings,

I'm having trouble understanding data types and using the function
xsl:sequence.

I have one common template that I call to create padding in my output
document:

<xsl:template name="pad-number">

  <xsl:param name="max" />
  <xsl:param name="char" />

  <xsl:sequence select="string-join((for $i in 1 to xs:integer($max) return
$char), '')"/>

</xsl:template>

So if I am padding for a text field, I pass in &#x20; for a space and if
it's a numeric field I use '0'.

My problem is (and I know this sounds silly) whenever I change from a text
to a numeric field there is an extra space inserted into the xsl:sequence
output.  This is a space and not the character I am passing into this
template.  So, if I use a tilda '~' instead of '&#x20;' I see the
appropriate number of tildas plus a space (hex code 20) in my output.

I do not have this problem when I am not changing from numeric to text, or
if I have consecutive numerics or consecutive text fields.

Perhaps I am not using the $max variable correctly?  I found the only way to
get it to work is when I specify xs:integer around it because the portion of
code that calls this template is performing a calculation and I think the
processor (Saxon 8.something) is creating a mandotory xs:double whenever a
calculation is performed.

This is probably a logic problem and has nothing to do with XSLT syntax but
I just thought I'd throw this out here and maybe one of the gurus on this
list could point me in the right direction.

Thanks,
Jim Neff

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



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