xsl-list
[Top] [All Lists]

Re: [xsl] xpath query

2008-01-20 08:28:23
Thanks again to all of you for all your valuable input and advice.

Michael, I picked up your book XSLT 2.0 programmers reference and I
look forward to reading that to help me out.

I have a question about your advice on how to think about these types
of things.  You say the following

"Don't 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"

I never realized these things worked that way.
I did not realize "Each invocation of the identity template processes
one node in the tree"
Why are there more than one invocations of the identity template.

I guess fundamentally I do not understand how the processor applies
the stylesheet templates to the xml document.

Say I have the followng XML

<root>
    <file name="test.java">
        <error line="4" message="Message1" severity="2"/>
        <error line="67" message="Message2" severity="4"/>
    </file>
    <file name="code.java">
        <error line="2" message="Message1" severity="2"/>
        <error line="54" message="Message2" severity="4"/>
        <error line="122" message="Message1" severity="2"/>
    </file>
</root>

Then as the processor processes the tree for this xml file, it finds
the <root> element, then looks for a template that matches it.
It would find the identity template and invoke this template.  At this
point, what does it put out to the result tree if anything?


Sean



On Jan 19, 2008 4:04 PM, Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:
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
equivalent.


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

child::*

as the set of child elements

and

child::*/child::*

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
http://www.saxonica.com/



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





-- 
Sean Tiley
sean(_dot_)tiley(_at_)gmail(_dot_)com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>