RE: [xsl] use of $foo/(//path)

Subject: RE: [xsl] use of $foo/(//path)
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 4 Feb 2008 22:44:23 -0000
> In this article:
> 
> http://www.stylusstudio.com/schema_aware.html
> 
> I noticed this:
> 
> <xsl:sequence select="$actor/(//video[actorRef=$actor/@id])"/>
> 
> The part which caught my eye was:
> 
> $actor/(//...)
> 

It's worth quoting the context:

<xsl:function name="f:videos-for-actor" as="schema-element(video)*">
   <xsl:param name="actor" as="schema-element(actor)"/>
   <xsl:sequence select="$actor/(//video[actorRef=$actor/@id])"/>
</xsl:function>

I think this can be a useful coding style within a function. There is no
context node in a function, but you can establish one using $x/EXP. So if
you want to evaluate a familiar expression within a function, but you can't
because there is no context node, just write $x/ in front of the expression
to set the context node to $x. This works, more or less, for any expression.
(The more-or-less is because there's a side-effect of forcing deduplication
and sorting into document order).

Similarly in XQuery rather than writing

for $x in EXP
return <a>
         <b>{$x/foo}</b>
         <c>{$x/bar}</c>
         etc
        </a>

I've been known to write

for $x in EXP
return $x/<a>
         <b>{foo}</b>
         <c>{bar}</c>
         etc
        </a>

which saves a few keystrokes.

Perhaps this is confusing, I don't know. I think it's worth experimenting -
constructs like this become familiar through usage, and some will survive,
other die. Perhaps using root() is less demanding on the reader. 

I've also been known to write

  <xsl:variable name="root" select="$actor/(/)"/>

Like the previous construct, this is eminently logical, but until it becomes
a familiar coding idiom, it might be more friendly to write
select="root($actor)" or "$actor/ancestor::document-node()".

Michael Kay
http://www.saxonica.com/

Current Thread