Reputation: 370
It seems that the xpath instance of
and castable as
operators provide me with a boolean result for a guess... In other words, i cannot find a way to discover the type of a variable without previously guessing it with an "yes or no" condition.
Let's say that I have no ideia what the type is, all I can do is ask if variable $x
has the data type of xs:string
, or if is actually an xs:integer
, etc, for all possible xslt datatypes, without getting a direct answer.
<xsl:function name="findType">
<xsl:param name="var"/>
<xsl:choose test="not(string(.) castable as xs:integer)">
<xsl:when test="$var instance of xs:integer">
<xsl:value-of select="'xs:integer'" />
</xsl:when>
<xsl:when test="$var instance of xs:string">
<xsl:value-of select="'xs:string'" />
</xsl:when>
...
<xsl:otherwise>
<xsl:value-of select="'unknown'" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
Is there a way to directly get the datatype of a variable, without the switch-case?
Upvotes: 0
Views: 3254
Reputation: 163595
In general, an XDM value belongs to an arbitrary number of types and it's meaningless to ask what "the type" is. This becomes most obvious with XPath 3.0 maps, where it becomes very clear that the type system is a lattice rather than a hierarchy.
With the vast majority of commonly-used values, however, there's a fairly intuitive notion of "the most specific user-visible type" of an item, and it's because this notion is intuitive rather than formal that you find it provided by extension functions rather than a built-in function. (Another reason is that types aren't first-class objects in XDM, so it's unclear how to represent the answer to the question "what is the type of X?").
A further objection to this functionality is that it can be easily misused. Asking if (typeof(X) == decimal) ...
would give the result "false" if X is an integer, despite integer being a subtype of decimal. If the implementation of abs(X)
changes so that it returns an integer when X is an integer, then existing code that asks whether the result is a decimal is going to break. The "instance of" operator is much safer.
Upvotes: 3
Reputation: 167716
See the approach taken in the three functions functx:node-kind
http://www.xsltfunctions.com/xsl/functx_node-kind.html, functx:atomic-type
http://www.xsltfunctions.com/xsl/functx_atomic-type.html and functx:sequence-type
http://www.xsltfunctions.com/xsl/functx_node-kind.html of the functx library http://www.xsltfunctions.com/.
Specific to the commercial editions (PE and EE of Saxon) you can also find http://saxonica.com/html/documentation/functions/saxon/type-annotation.html and http://saxonica.com/html/documentation/functions/saxon/type.html useful.
Upvotes: 1