This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Same name Elements in more than one node


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@mulberrytech.com
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]