[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Assigning types to variables


Subject: Re: [xsl] Assigning types to variables
From: David Carlisle <davidc@xxxxxxxxx>
Date: Wed, 13 Sep 2006 16:13:17 +0100

if you use an as attribute the variable is bound to the sequence
constructed, so in your case 
$test is an element node with name one (this is an element node with no
parent, something that can not exist in xslt1)

so $test is element one and
$test/two selects its child element with name 2.

If you do not use an as attribute and use content rather than a select
attribute the xsl:variable works as in xslt1 and always generates a
single document node / and any generated content is made a child of that
node (by copying).

so in the second case $test is / $test/one is its child and
$test/one/two is its child.

> Also could you advise what type I should be using for this kind of
> task?

it doesn't make much difference in your case with a single constructed
element (except it changes the way you access it, as you found) but
consider

<xsl:variable name="test" as="element()*">
  <a/>
  <b/>
</xsl:variable>

That's a sequence of two parentless  elements, so having no parents
they are not siblings so $test/self::a/following-sibling::b is empty


<xsl:variable name="test">
  <a/>
  <b/>
</xsl:variable>

is a / node with a and b children so
$test/a/following-sibling::b
is the b node.

so, if you think you might want to wander around via axis paths
parentless nodes can be confusing, but there is sometimes a big, big win
for using as="element()*
if you have
<xsl:variable name="test" as="element()*">
  <xsl:sequence select="foo/bar"/>
</xsl:variable>
then its like
<xsl:variable name="test"  select="foo/bar"/>
and selects all the foo/bar elements but selects the existing nodes so
selecting
$test/foo[1]/bar[1]/../../../x/y
may well work and seelct something in the original tree
<xsl:variable name="test"">
  <xsl:sequence select="foo/bar"/>
</xsl:variable>
on teh other hand generates a new / node and creates children of this
node by _copying_ the nodes
so now
$test/foo[1]/bar[1]/../../../x/y
will definitely be empty as going up teo from teh bar elements will get
you to the / at the top of this element.

bviously you don't want to copy whole document trees when you don't need
to, but often the system won't really copy it anyway (if i understand MK
correctly) but using as= makes ypu less reliant on the optimiser
spotting that it can reuse nodes without actually copying them.


This is going to be a faq....

David


Current Thread