RE: [xsl] xpath query

Subject: RE: [xsl] xpath query
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sat, 19 Jan 2008 21:04:45 -0000
> I have 2 questions though.
> 1) - In the first template that copies the original xml, the 
> expression select="@* | node()" What is this saying?
> I read it is another way of phrasing this select="attribute() |
> element() | text() | comment() | processing-instruction()" 

The expanded form of @*|node() is attribute::*|child::node(), which selects
all attributes and all children. The children will all be elements, text
nodes, comments, and processing instructions, so your expanded form is

> 2) - Also related to the first template. Why do I need the 
> <xsl:template match="@* | node()"> and <xsl:apply-templates 
> select="@* | node()"/> in the <xsl:copy/> tag?
> I would have thought in the template match "/" would have sufficed.
> (When I try that, I just get the values from the nodes).

Each invocation of the identity template processes one node in the tree. The
template is designed to match any node (except a document or namespace
node), to do a shallow copy of that node, and then to process its children.
If this is the only template rule in the stylesheet then the final effect is
to copy the whole tree. But of course the whole idea is to override this
behaviour for selected nodes, those which you don't want to copy exactly.
> Also in the thread Abel stated
> >I think many people find this at first confusing: when do you get a 
> >node set, when do you get one node, when do you get a sequence or a 
> >sequence of nodes, when do you need apply-templates, when 
> for-each or 
> >for-each-group etc etc. Getting it straight is vital for 
> working with 
> >XSLT without frustration.
> Do you know of any resources, either online or in print that 
> explain these concepts well with good examples?  I would 
> really like to make this confusion a thing of the past for myself.

Abel is right that this is one of the things people sometimes have
difficulty with (I did a class last week and some of my students got quite
stuck on this). Of course there are quite a few other "advanced" concepts in
XSLT, and different people have problems with different concepts. I try to
spend a lot of time explaining fundamental concepts in my XSLT reference
book, to try and help people over these hurdles. 

Actually I find there are two kinds of programmers: those who write code by
copying/pasting examples, and those who need to understand the concepts
first. The latter sometimes seem to be taking longer to learn but in the
end, of course, it is these people who become the experts. So I think it's
always a great sign when people ask this kind of question.

I think the best advice I can give on this is the same as the advice people
are given when learning SQL: try to manipulate sets (or sequences) of values
as a whole wherever possible, rather than thinking of your code in terms of
loops that process one item at a time. So think of


as the set of child elements



as the set of grandchildren - think of child() as a function that takes a
set of nodes as input and produces the set containing their children as
output. Then "/" is a function application: think of it as
children(children(.)). Dont think of it as a nested loop that iterates over
the children and then over their children. Once you've got this into your
head, try to think of xsl:for-each the same way - not as a loop, but as a
function which applies the body of the instruction to the set of nodes
selected by the select expression.

Michael Kay

Current Thread