passing in an element as a parameter to a stylesheet

A

Andy Fish

hi,

I have a stylesheet which accepts a parameter 'foo' whch is an XML element
(.Net 2.0 - I'm not sure if this is platform specific)

now, when I do

<xsl:apply-templates select=$foo />

this matches the following template:

<xsl:template match="/">

which I was expecting to only match the root of the input document (this
confused me at first but it's obviously because the element passed in is
effectively a root element)

the question is, is there a way to match only the root node element of the
input document rather than the root element of a stylesheet parameter

Andy
 
R

Richard Tobin

Andy Fish said:
the question is, is there a way to match only the root node element of the
input document rather than the root element of a stylesheet parameter

match="/" doesn't match the root element, it matches the root node which
is above the root element (so that it can contain, for example, processing
instructions before the root element). But I don't think that matters to
your question, which is how to distinguish the root node of the
input document from the root node of other documents.

The only way I can think of to do this is to bind a variable to the
root node of the input document:

<xsl:variable name="input-root" select="/"/>

(which works because top-level variable declarations have the root node
of the input document as their current node) and compare the node against
that, for example

<xsl:template match="/[count(.|$input-root) = 1]">

("count($a|$b)=1" is a way of testing two nodes for identity - if they're
the same then the set containing both of them will only have one element).

I haven't tested this.

-- Richard
 
B

Bjoern Hoehrmann

* Richard Tobin wrote in comp.text.xml:
distinguish the root node of the input document from the root node
of other documents.

The only way I can think of to do this is to bind a variable to the
root node of the input document:

generate-id($a) = generate-id($b) would do.
 
B

Bjoern Hoehrmann

* Richard Tobin wrote in comp.text.xml:
But I don't think that matters to your question, which is how to
distinguish the root node of the input document from the root node
of other documents.

The only way I can think of to do this is to bind a variable to the
root node of the input document:

generate-id($a) = generate-id($b) would do.
 
D

David Carlisle

Richard said:
<xsl:template match="/[count(.|$input-root) = 1]">

you could so that in XSLT 2.0 but not on 1.0 (which the OP is using)
which doesn't allow variables in match patterns.

the usual technique here is just not to apply templates to / on the
parameter but rather to its top level element,
so don't do

<xsl:apply-templates select="$foo" />

do

<xsl:apply-templates select="$foo/*" />

David
 
R

Richard Tobin

generate-id($a) = generate-id($b) would do.
[/QUOTE]
That's definitely the simplest way to test is-same-node in XSLT 1.0.

Why is it simpler than "count($a|$b)=1" ?

I agree it may be simpler to explain.

I believe that using generate-id() is likely to be much more expensive
in most processors, but of course this only matters when it's used
heavily.

-- Richard
 
D

David Carlisle

That's definitely the simplest way to test is-same-node in XSLT 1.0.

Why is it simpler than "count($a|$b)=1" ?

I agree it may be simpler to explain.

I believe that using generate-id() is likely to be much more expensive
in most processors, but of course this only matters when it's used
heavily.

-- Richard[/QUOTE]
this came up a while ago on xsl-list and someone (Jeni I think) did a
survey of popular processors and it was about 50-50 which idiom was
quicker. On saxon at that time count() was a lot faster than using
generate-id, so Mike changed things so saxon special cases the
generate-id($a)=generate-id($b) idiom and rewrites it to an internal
form which just checks same-node without actually computing the unique
id, ie it uses an internal (for xpath1) operator equivalent to xpath 2's
is operator. This is of course a lot faster. Though as you say, you need
to be doing a lot of them before you can really tell the difference.

David
 
J

Joe Kesselman

I believe that using generate-id() is likely to be much more expensive
In Xalan, generate-id() is based on an internal "node ID" number already
associated with the node, so it's pretty much int-to-string plus a
concatenate (since the ID has to start with a letter). That's probably a
bit more expensive than building a nodeset followed by checking its
length, but not enough that you're likely to notice it unless it's in
the innermost layer of a tight loop.

If there's a real-world use-case where it does make a real performance
difference, I'd be interested in knowing about it. Either idiom could
probably be special-case optimized, but I wouldn't suggest investing
coding effort in doing so until that's shown to actually make a
difference -- there are lots of other places to invest tuning effort.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top