This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Scalar -> node-set conversion (was How to distinguish b/n a scalar and a node-set)
- To: "'xsl-list at mulberrytech dot com'" <xsl-list at mulberrytech dot com>
- Subject: Scalar -> node-set conversion (was How to distinguish b/n a scalar and a node-set)
- From: Andrew Kimball <akimball at microsoft dot com>
- Date: Fri, 3 Nov 2000 14:35:00 -0800
- Reply-To: xsl-list at mulberrytech dot com
Dmitre wrote:
> This is a good idea and it actually works in MSXML 3:
>
> count(node-set(nodeSet) | node-set(nodeSet)) returns 1.
> count(node-set(Scalar) | node-set(Scalar)) returns 2.
>
> Unfortunately, Saxon always returns 1.
>
> Also, I've heard that the standard node-set() function in XSLT 1.1 will
> throw error when passed a scalar argument.
MSXML3 converts to a node-set using the following rules:
1. A result tree fragment (RTF) is converted into a node-set containing a
single node (the root node of the fragment).
2. A string value is first converted into an RTF by creating a fragment with
one text node child whose text is the string value. The resulting RTF is
then converted to a node-set according to rule #1.
3. Values of any other type are first converted to a string as if by a call
to the string() function. Rule #2 is then used to convert the resulting
string to a node-set.
Not treating the scalar->node-set conversion as an error leads to a nice
symmetry between the different types--converting any type to a node-set and
then back again will result in the original value.
Also, allowing the scalar->node-set conversion allows for some potentially
interesting for-each loops (this one searches for a constant set of cities
within the $cities document):
<xsl:for-each select="node-set('Boston') | node-set('New York')">
<xsl:element name="{.}">
<xsl:if test=". = $cities/city">
<xsl:text>Found</xsl:text>
</xsl:if>
</xsl:element>
</xsl:for-each>
Of course, this operation could be accomplished in other ways, but it seems
more convenient to do it this way. If an implicit conversion from scalar to
node-set was allowed, then the example becomes even simpler:
<xsl:for-each select="'Boston' | 'New York'>
Given the frequent (mis)use of RTF's:
<xsl:variable name="city">Boston</xsl:variable> instead of
<xsl:variable name="city" select="'Boston'"/>
it probably makes sense to most people that a constant string = an RTF
having a single constant text child (and RTF = node-set having a single
node).
~Andy Kimball
MSXSL Dev
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list