RE: How dynamic is XSL?

Subject: RE: How dynamic is XSL?
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 10 Aug 2000 20:55:58 +0100
Søren,

In your root-node-matching template, you have the instruction
<xsl:apply-templates />.  When the processor sees this instruction, it
starts looking at each of the children of the current node (in this case
the 'card'), trying to find a template that matches them.

If you look at your source XML, the card element has the following children:
* cardid
* cardtitle
* img
* text
* link
* link

You've written templates matching 'img' and 'text' and 'link', so when
these child elements are found, then those templates are run on them.

With 'cardid' and 'cardtitle', however, there aren't any matching templates
explicitly in your stylesheet.  In these cases, the XSLT processor uses the
'built-in templates'.  There are two built-in templates:

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

The first built-in template matches against any element, or the root node.
All it does it apply templates to *its* children.  This means that by
default templates are applied to all the descendents of the root node,
unless you interrupt that by defining templates of your own.

The second built-in template matches against any text node or any
attribute.  What *it* does is output the value of the text node.  So by
default, if you apply templates on an element, its content will be output.

In your case, the first built-in template matches 'cardid' and 'cardtitle'.
 So their children have templates applied to them.  'cardid' has a single
child, the text node "index".  This text node matches against the second
built-in template, so the value of the text node (i.e. the string 'index')
is outputted.  A similar thing happens with 'cardtitle', resulting in the
two strings, 'index' and 'WAP XML Test' appearing in your output.

There are two ways you can stop this happening.  The first is to define a
template that matches on these two elements and does nothing with them (an
empty template), to prevent their content being processed:

<xsl:template match="cardid | cardtitle" />

The second way is, within your root-node-matching template, only apply
templates on the elements you're actually interested in:

<xsl:apply-templates select="img | text | link" />

Which works better depends on the situation.  If it's more work to list the
elements that you *don't* want to process, or if it's about equal, then
it's best to use xsl:apply-templates on a limited set of nodes, because
this reduces the amount of processing that the XSLT Processor has to do.
If it's more work to list the elements that you *do* want to process, then
use the empty template instead.

I hope this makes things clearer,

Jeni

Dr Jeni Tennison
Epistemics Ltd * Strelley Hall * Nottingham * NG8 6PE
tel: 0115 906 1301 * fax: 0115 906 1304 * email: jeni.tennison@xxxxxxxxxxxxxxxx


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


Current Thread