[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: [XSLT 2.0] Determining the datatype of the value

Subject: RE: [XSLT 2.0] Determining the datatype of the value returned from a function?
From: "Roger L. Costello" <costello@xxxxxxxxx>
Date: Fri, 17 Jun 2005 13:59:45 -0400
xsl eq
Many thanks David.  A subtle, but extremely important point.
 
I figure that others may encounter this problem, so below I have summarized
the problem and its solution.  /Roger

Determining the datatype of the value returned by a function

Suppose that you want to create an XSLT function which returns a value that
may be one of any number of different (atomic) datatypes, e.g., xs:integer,
xs:double, xs:decimal, xs:string, etc.  

With the value that the function returns you would like to determine its
datatype.  For example, if the function returns the integer 5 then: 

 "$value instance of xs:integer" 

should yield true (assume that $value is a variable that holds the value
returned from the function).

Here is an example that shows invoking a function and then testing the value
that is
returned to determine its datatype:

<xsl:template match="/">
    <xsl:variable name="test1" select="'A'"/>
    <xsl:variable name="value" select="ex:Test($test1)"/>
    <xsl:choose>
        <xsl:when test="$value instance of xsd:integer">
            <xsl:message>INTEGER</xsl:message>
        </xsl:when>
        <xsl:when test="$value instance of xsd:string">
            <xsl:message>STRING</xsl:message>
        </xsl:when>
        ...
        <xsl:otherwise>
             <xsl:message>OTHER</xsl:message>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

How you design the function is crucial.  The below function gives
undesirable results.
It always returns a text node that contains a string value:

<xsl:function name="ex:Test">
    <xsl:param name="letter"/>
    <xsl:choose>
         <xsl:when test="$letter eq 'A'">
             <xsl:variable name="num" select="5" as="xsd:integer"/>
             <xsl:value-of select="$num"/>
         </xsl:when>
         <xsl:when test="$letter eq 'B'">
             <xsl:variable name="num" select="5.00" as="xsd:decimal"/>
             <xsl:value-of select="$num"/>
         </xsl:when>
         ...
         <xsl:otherwise>
             <xsl:variable name="message" select="'Error'" as="xsd:string"/>
             <xsl:value-of select="$message"/>
         </xsl:otherwise>
    </xsl:choose>
</xsl:function>

Consider this code snippet:

<xsl:variable name="num" select="5" as="xsd:integer"/>
<xsl:value-of select="$num"/>

You might think that the xsl:value-of element will output an integer 5.
In fact, it will not.  The xsl:value-of statement always outputs:
1. A text node, and
2. The datatype of the value in the text node is always string.
That is, with the xsl:value-of element you will always loose 
datatype information.  Beware!

Now consider this code snippet:

<xsl:variable name="num" select="5" as="xsd:integer"/>
<xsl:sequence select="$num"/>

The xsl:sequence element behaves very differently from the xsl:value-of
element.  In the above example, the xsl:sequence element will simply
output the number 5, with the integer datatype intact.
So, if we want to create a function that returns an atomic value, and we
want
the datatype of the atomic value intact, then the function must use
xsl:sequence,
and it must not use xsl:value-of.

Here is the correct way to design the function:

<xsl:function name="ex:Test">
    <xsl:param name="letter"/>
    <xsl:choose>
         <xsl:when test="$letter eq 'A'">
             <xsl:variable name="num" select="5" as="xsd:integer"/>
             <xsl:sequence select="$num"/>
         </xsl:when>
         <xsl:when test="$letter eq 'B'">
             <xsl:variable name="num" select="5.00" as="xsd:decimal"/>
             <xsl:sequence select="$num"/>
         </xsl:when>
         ...
         <xsl:otherwise>
             <xsl:variable name="message" select="'Error'" as="xsd:string"/>
             <xsl:sequence select="$message"/>
         </xsl:otherwise>
    </xsl:choose>
</xsl:function>

Here's a complete example, that works as desired:

<xsl:function name="ex:Test">
    <xsl:param name="letter"/>
    <xsl:choose>
         <xsl:when test="$letter eq 'A'">
             <xsl:variable name="num" select="5" as="xsd:integer"/>
             <xsl:sequence select="$num"/>
         </xsl:when>
         <xsl:otherwise>
             <xsl:variable name="message" select="'Error'" as="xsd:string"/>
             <xsl:sequence select="$message"/>
         </xsl:otherwise>
    </xsl:choose>
</xsl:function>

<xsl:template match="/">
    <xsl:variable name="test1" select="'A'"/>
    <xsl:variable name="result" select="ex:Test($test1)"/>
    <xsl:choose>
        <xsl:when test="$result instance of xsd:integer">
            <xsl:message>INTEGER</xsl:message>
        </xsl:when>
        <xsl:when test="$result instance of xsd:string">
            <xsl:message>STRING</xsl:message>
        </xsl:when>
        <xsl:when test="$result instance of xdt:anyAtomicType">
            <xsl:message>xdt:anyAtomicType</xsl:message>
        </xsl:when>
        <xsl:when test="$result instance of text()">
            <xsl:message>text()</xsl:message>
        </xsl:when>
        <xsl:otherwise>
             <xsl:message>OTHER</xsl:message>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.