In article <slrnc9pgrp.ie1.alsbergt@dexter.zoopee.org>,
Tom Alsberg <alsbergt@softhome.net> wrote:
% * Is there a way to "enter" a child element of the currently matched
% element in the template, so that XPath expressions inside would be
% relative to that node? Specifically, I want to do this, in order to
You could use a mode specific to that element
<xsl:template match='frankenstein'>
<xsl:apply-templates mode='child-of-frankenstein'/>
<xsl:template>
this will work with call-template as well. You can also use for-each.
The XPath expressions in for-each will be relative to the node
currently being processed.
% * How can I logically AND two expressions in an XPath boolean
% expression?
Using `and'.
% * Can I define more than one template for a match, with one being the
% default, but being able to select different ones with
% xsl:apply-templates? (I understand that modes are only to select
% which elements to process, not which of a few templates to apply to
% an element)
No, modes are to select which of a few templates to apply to an element.
Anyway, there are a few things which might deal with your problem.
You can assign a predicate to a match expression, and use that to
decide which template to apply
<xsl:template match="car[@colour ='blue']">
...
</xsl:template>
<xsl:template match="car[@colour ='red']">
...
</xsl:template>
<xsl:template match="car">
...
</xsl:template>
Roughly speaking, the XSLT processor will choose the most specific
template which matches a node. It's an error to have two equally
specific templates which match the same node, though.
You can set the priority on a match. For instance, if you could have
templates to match cars by the number of doors and a template to match
cars by colour, and say the colour is more important:
<xsl:template match="car[@colour ='blue']" priority='2'>
...
</xsl:template>
<xsl:template match="car[@colour ='red']" priority='2'>
...
</xsl:template>
<xsl:template match='car[@doors = '2'] priority = '1'>
...
</xsl:template>
<xsl:template match='car[@doors = '4'] priority = '1'>
...
</xsl:template>
<xsl:template match="car" priority = '0'>
...
</xsl:template>
This would match the first template for all blue cars, the second template
for all red cars, the third for all cars with 2 doors which are neither
blue nor red, and the fourth for all cars with 4 doors which are neither
blue nor red. The final template would be used for cars which have a
different number of doors or don't have enough information to match
the previous four templates.
% What I'm right now working on is defining an XSD type for human names:
For a tiny subset of humans (says a guy with two middle names :).
% What I want, is to have in an XSL stylesheet, a few different
% templates for processing a personname, and be able to, in different
% contexts (in the same stylesheet), call different templates for it.
Sounds you want to use a mode to me. Define a template with a mode
<!-- format a name, current node should be a name element.
also, this should take into account names that run surname givenname
and probably all sorts of other things I can't be bothered with now -->
<xsl:template name='format-name' mode='formal'>
<xsl:value-of select='title'/>
<xsl:text> </xsl:text>
<xsl:value-of select='given'/>
<xsl:text> </xsl:text>
<xsl:value-of select='middle'/>
<xsl:text> </xsl:text>
<xsl:value-of select='surname'/>
</xsl:template>
<xsl:template name='format-name' mode='informal'>
<xsl:value-of select='given'/>
<xsl:text> </xsl:text>
<xsl:value-of select='surname'/>
</xsl:template>
<xsl:template name='format-name' mode='anal'>
<xsl:value-of select='title'/>
<xsl:text> </xsl:text>
<xsl:value-of select='given'/>
<xsl:text> </xsl:text>
<xsl:value-of select='middle'/>
<xsl:text> </xsl:text>
<xsl:value-of select='surname'/>
<xsl:text> </xsl:text>
<xsl:value-of select='suffix'/>
</xsl:template>
Which you would call like this:
<xsl:text>I dined with </xsl:text>
<xsl:call-template name='format-name' mode='anal'>
<xsl:text> last week and I was very interesting.</xsl:text>
--
Patrick TJ McPhee
East York Canada
ptjm@interlog.com