This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Scalar -> node-set conversion (was How to distinguish b/n a scalar and a node-set)


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]