RE: [xsl] Determining the context node

Subject: RE: [xsl] Determining the context node
From: "Allison Bloodworth" <abloodworth@xxxxxxxxxxxx>
Date: Thu, 13 Apr 2006 09:20:26 -0700
Hi Evan & everyone, 

Thanks very much for your help--the context node has often confused me and
this message from Evan is the most helpful information on it I've ever
gotten (especially the part about for-each and apply-templates being the
only things that change it). <xsl:value-of select="name()"/> is exactly what
I was looking for. 

Re: xsl:copy, since I didn't know how to get the name of the node, I was
trying to print out the content of the node using either xsl:copy or
xsl:copy-of. I would think the only real way you could do this is to use
xsl:copy...with xsl:copy-of if the current node had no text content (and
perhaps contained other elements), you would get the text content of all the
element(s) below it so you couldn't really tell what node you were on if you
were in a deep tree structure. The problem with xsl:copy, however, was that
if you were on a node with no text content itself (e.g. the node only
contained other elements) you would get nothing. 

Thanks again!
Allison

-----Original Message-----
From: Evan Lenz [mailto:evan@xxxxxxxxxxxx] 
Sent: Wednesday, April 12, 2006 10:59 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Determining the context node

Hi Allison,

<xsl:value-of select="name()"/> will print the name of the current node 
(if it has a name) to the output.

Also, the local-name() function returns just the local part, and 
namespace-uri() returns the namespace URI part.

Each of these functions take a node-set as an argument (and operate on 
just the first node in the set if there's more than one), but the 
default argument is the context node, so that writing name(.) is 
equivalent to name(), for example.

For debugging, you may also want to look at <xsl:message>, the content 
of which most processors print to stderr output.

As far as keeping track of the context node goes, I try to write my code 
in such a way as to make this as transparent as possible. Bite-sized 
template rules, for example, let you look up just a few lines to see 
what the match attribute says, which often gives you a good hint as to 
the context, as long as the pattern is not completely generic like *. 
But even then you at least know it's an element.

This is also one of the reasons why I try to avoid using 
xsl:call-template when context will be relevant. Instead, I use 
xsl:apply-templates with a particular mode name. Named templates don't 
give you any hints about the context. All you know is that the context 
is the same as the context of the corresponding xsl:call-template. But 
if you use a template rule instead (i.e. with a "match" attribute and 
invoked with xsl:apply-templates), then you can build in some 
documentation about your context without having to write any comments 
(which have the potential of getting out of sync).

The key things to remember about the current node:

1. Only two instructions change it: <xsl:for-each> and <xsl:apply-templates>
2. <xsl:call-template> does *not* change the context

I hope this helps. Once you've fully grasped context in XSLT, you'll be 
well on your way to mastery :-)

I'm afraid I can't address your question about xsl:copy, because I can't 
make sense of it, given the way you've stated it. Maybe an example would 
help.

Evan


Allison Bloodworth wrote:
> Hi, 
>
> I sometimes get confused about what the context node is when I'm writing a
> complicated XSL stylesheet. I'm wondering if someone can suggest an easy
way
> to determine what node I'm on (e.g. by using some code to print this info
> out to my output)? 
>
> I've tried xsl:copy, xsl:copy-of, and xsl:value-of, but I don't want to
know
> the value of the element, I want to know the name of the element (e.g. for
> <EventWebsite>www.berkeley.edu</EventWebsite> I want to know that I'm on
> EventWebsite, not that the value is www.berkeley.edu). Also, because most
of
> my elements contain other elements instead of text, often doing xsl:copy
> (which is more rational than using copy-of) doesn't get me anything. I
> assume there's probably an easy XPath expression for this, but even after
> doing quite a bit of research I can't find it.
>
> Thanks for any suggestions on this!
>
> Allison Bloodworth
> Principal Administrative Analyst
> Technology Program Office
> University of California, Berkeley
> (415) 377-8243
> abloodworth@xxxxxxxxxxxx

Current Thread