Re: [xsl] Same name Elements in more than one node

Subject: Re: [xsl] Same name Elements in more than one node
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 26 Dec 2001 17:40:02 -0500
Mike,

Thanks for posting your various reservations about templates. We are often so dogmatic as, maybe, to scare off legitimate reasons for hesitating. I'll try to give some response to elucidate their mysteries -- but I'm hoping that others (you know who you are) will also put an oar in....

At 03:43 PM 12/26/01, you wrote:
Yes, templates seem to me to be the answer. However, I do have some
reservations in using them. Mostly my problems are the result of
ignorance. I have tried to educate myself in their usage from Michael
Kay's book (1st edition), but I have been unable to untangle some
complexities in their usage.

As a community, we are still grappling with issues of why XSLT seems hard, to many, to learn, why it's hard to teach oneself, and how to explain best these various complexities. There's really no help for it but to do what we're doing.


1. Calling them "select" or "match"?
Initally I have a problem with how they are called. Is the name that
they are referred to have to be the same as the element they refer
to? Or are they used like Labels (each having a unique name)?

Ah. Well, templates can have a label, called a 'name', and so can be used in this way. (You can call a named template with an xsl:call-template instruction.) But more commonly a template is distinguished from other templates by its 'match' attribute --


<xsl:template match="C01"> ... </xsl:template>
will match elements name C01

<xsl:template match="C01[@level='box']">...</xsl:template>
will match elements named C01 that have a 'level' attribute with value 'box'

Generally, however, you don't fire a template by referring to it. (When you want to do this, you use xsl:call-template.) Rather, you simply say "process these nodes now, using their templates" -- so what you are identifying is not the template, but rather the node ... then the processor finds the template.

It's designed this way because the expectation is that most transforms will proceed node by node through the source tree, for the most part following its original order. As a consequence, it's the source tree, not the organization of templates in the stylesheet, that drives processing and determines "control flow". This processing model works very well for a wide range of different kinds of data, especially "documentary" data like your finding aids.

Don't confuse the <xsl:apply-templates/> instruction with a template. In fact, apply-templates is really the Yang (I like to say) to a template's Yin. xsl:apply-templates is the instruction that says "pick these nodes and process them using their templates" -- that's why it has a 'select' attribute.

A template never has a 'select' attribute. Instead it has a 'match' attribute (identifying when it can be fired), a 'name' attribute (allowing it to be fired by name) or both.

I am used to assigning functions based on conditions using "call" and
"goto" followed by the label name. These take you out of the main
loop so that a function can be completed at a certain step and then
return you to your main loop again. However, I find it very unclear
as to what my template will be named and what attribute will be used.
The examples seem to run the gamit as full paths as well as names
that are derived from the elements they are processing.

Thinking of it as like a 'goto' or a 'call' with a label saying where to go or what to call will get you in trouble. It's not like that. The occasions where it is are really the exception (that prove the rule).


Instead, think of your source tree, pay attention to your source tree, watch your source tree!

It may also help you to know that there are built-in templates that will fire by default if you ever say apply-templates and select a node for which you have no template explicitly. Mike's book covers this.

2. Node addressed.
I find it very unclear as to when I call up my template how it will
be effected by the node I am currently functioning in. If I am let's
say in an <xsl:for-each select="//C02"> and I call up a template that
has to do with the <C03> child, do I assume that I must give the
entire path to the element beginning from //C02? I find this all the
more unclear when I have same name elements in parent and child
nodes.

Yes. This is the notion of the "context node" I was referring to (and the "current node" of which Oleg spoke).


Whenever something happens in XSLT, the processor knows what its current node is and what its context node is. Usually these are the same. The current node is "whatever node I'm processing now". In most cases, your current node is whatever node the template has matched and is now processing (and you have always matched a template, even if it's the one matching the root, or it's a built-in template that has fired by default). But a for-each instruction changes the current node (and the current node list).

The current node plays a critical role in evaluating XPath:

//C02 traverses from the root and picks up all its C02 descendants
./C02 traverses from the current node and picks up all its C02 child elements
.//C02 traverses from the current node and picks up all its C02 descendants (but none others)
C02 is the same as ./C02, only more efficient and easier to write


Think of the role of the current node as being analogous to the current directory when using UNIX directory paths to traverse a file system. XPath is designed to have a loose resemblance to this notation, which most XSLers are expected to find familiar.

When speaking strictly, we often say "context node" because it's the context node that is actually referred to, and it's not always the same. E.g.

./C02[@level='box'] traverses from the current node to all its C02 children, and then filters to include only those whose 'level' attribute has the value 'box'. The *context node* for the XPath expression '@level' is each of the C02 nodes selected by the expression ./C02, *not* the current node (which is the context node for the entire expression).

3. Order of templates
I also find it unclear as to how the templates will appear in my
output. Is there are certain order that templates are executed? If I
just type <xsl:apply-templates> in my stylesheet, is the order of
their execution have a specific default (top down, etc.)?

The order of their execution is generally determined by the order of the source document, not the order of templates in the stylesheet. That's why the source document is what you watch.


Finally, I would love to see a protocol for delimiters in
expressions. What I am referring to is in the expression:

<xsl:value-of select=""/>

If I write an expression in the "" should my order be

1. "" (i.e., select="Expression")
2. [] (i.e., select="[Expression]")
3. () (i.e., select="[(Expression)]")
4. '' (i.e., select="[('Expression')]")
5. {} (i.e., select="[('{Expression}')]")

I would very much like to see something like this but I have been
unable to find it so far (my novice experience I grant).

I think you're mistaking the way the [] syntax works. The construction is called a 'predicate' and I suggest you look it up in Mike's book. These are not interchangeable delimiters.


It becomes really hairy when you want to designate a string in the
middle of all this. I assume that a string must have '' around it,
but what if you are already at that level in your expression? Is
there another delimiter that can be used? I end up writing stuff like
this:

<xsl:value-of
select="//PERSNAME[@ENCODINGANALOG='100$a'][2][not(.=preceding::PERSNAME)]"/>

So is there a limit as to how many [] the parser will read and
process?

No. The expression you wrote above translates into English as


"Descending from the root, of all descendant PERSNAME elements whose ENCODINGANALOG attribute has the value '100$a', those which are the second child of their parent, but only if their value is not equal to the value of any preceding PERSNAME element."

That is, the predicates (expressions in []) are applied as filters to the node sets to which each applies, in the sequence in which they are written. (A predicate works by evaluating the predicated expression with each node in the node set in turn as its context node, and returning only those nodes for which the predicated expression evaluates as Boolean "true".)

It seems to me that some of these have specific uses such as {}.

They all do.


Also, an NOT list would be nice as well.

"Not" can generally be handled. Ask this list when you have a specific case and we'll show you. (For example, select="*[not(self::C01)]" will get all element children of the current node that are not C01 elements.)


I guess this is something you learn in programming school. I admit I
am a haack, so if I could trouble someone to spell it out for me. I
would really appreciate it.

Well, actually not, programming schools are not teaching it yet. If you want to learn it, you can either hire us (my employer, Mulberry Technologies :-) or Ken Holman (hi Ken!) or Bob DuCharme (Bob you teach this stuff don't you?) or any number of people ... or you can try one of the numerous "Internet academies" or quick-training operations that have sprung up to help with web technologies (though often there you'll get a non-practitioner trying to teach you -- not a good idea), or do what you're doing -- try things out, read the books, ask the list, be patient.


Above all, I find that "be patient" is important. Often people ask the list -- or worse, run around in circles tearing their hair out -- when a few hours of careful, concerted, hands-on study of one of the increasing number of how-to books would answer most questions before they ever need to be asked -- thus saving many more hours in the long run.

Fortunately, the availability of books suitable for beginners has much improved over the last few months. As of a year ago, Mike Kay was about all there was (unless you actually wanted to slosh through the fens of Microsoft's WD-XSL) -- and even Mike's is strictly a "Programmer's Reference" not a tutorial or introduction. Now there are

Bob DuCharme, "XSL Quickly"
John Gardner and Zarella Rendon, "XSLT & XPath: A Guide to XML Transformations"
Steven Holzner, "Inside XSLT"
Michael Fitzgerald, "XSL Essentials"
John Simpson, "Just XSL"

... at least! (Sorry anyone if I left you out!) None of these will lead you down the garden path (into the fens :-), and any of them could be really good.

The two things you need to master first are:
* template-based processing (focus on exactly the questions you asked)
* current nodes, context nodes and XPath expressions

Good luck!
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread