<xsl:template>
We have just looked at <xsl:output>,
which is known as
a top-level
element as it can only occur as a child of the <xsl:stylesheet>
element. We'll now look at <xsl:template>,
which is
another top-level element.
The <xsl:template>
element contains
the information required to produce a node in the result tree. We have seen
several examples in the stylesheets we have been producing.
In the examples we have used so far, we have employed a match
attribute, for example:
<xsl:template match="EXTRACT">
The attribute value is an XPath expression that will tell us
which nodes in the source tree will cause this template to execute.
When using XPath expressions, there is always the
possibility that several templates will match a single element. For example, if
you look back to the listing of HamletExtract.xml,
you will see that
both acts and scenes have titles. In our previous stylesheet Hamlet.xsl,
we had the templates:
<xsl:template
match="ACT/TITLE">
<H1><xsl:value-of select="."/></H1>
</xsl:template>
<xsl:template
match="SCENE/TITLE">
<H2><xsl:value-of select="."/></H2>
</xsl:template>
What if we had another template:
<xsl:template match="TITLE">
<P><xsl:value-of select="."/></P>
</xsl:template>
Which template would be executed when our <xsl:apply-templates>
finds a scene's title?
One thing we can do is add a priority
attribute to the <template> element:
<xsl:template match="TITLE"
priority="1">
<P><xsl:value-of
select="."/></P>
</xsl:template>
This will allow the stylesheet to select the highest
priority template, and only execute that. The value of the priority
attribute can be any positive or negative integer or real number: the higher
the number, the
higher the priority. The default priority is between -0.5 and 0.5, so this new
template will always be matched for any <TITLE>
element, and the more
specific ACT/TITLE
and SCENE/TITLE
templates will never be matched.
This is just one method of resolving conflicts when there
are multiple templates matching a pattern. Later, in the section Template
Match Conflicts, we will look
at the others and the rules that determine in general which template is
instantiated.
The <xsl:template>
element has two
further optional attributes. One is name,
which is used with the <xsl:call-template>
element, and the other is mode,
which provides additional
flexibility in the use of templates. We will meet both these attributes in
Chapters 4 and 5.
<xsl:apply-templates>
Along with the <xsl:template> and <xsl:value-of>
elements, this is the workhorse of the XSLT world. It is the element that
controls which templates are used at any point while building the result tree.
It can have two
attributes, of which we have already met the select attribute. This
simply takes as its value an XPath expression that controls which elements in
the source tree will be processed. This pattern can be simple, like most of
those we have been using, or much more complicated, using any of the rules of
XPath. Note that the select attribute is optional. If it is missing, all child
nodes will be processed.
The second attribute is the mode
attribute. Since this relates to the mode
attribute in <xsl:template>,
we will again be leaving this to Chapter 4.
As well as its attributes, <xsl:apply-templates>
can have two sub-elements. The first is <xsl:sort>,
which alters the
order in which selected nodes are processed, and the second is <xsl:with-param>,
which provides a method of passing parameters to templates. We will look at <xsl:sort>
shortly, but leave <xsl:with-param> to Chapter 4.
<xsl:value-of>
This element is always contained within a template and
simply writes the text node (or nodes) of the element pointed to by the XPath
expression identified in its select
attribute to the result tree.
The select
attribute works in much the
same way as it does in <xsl:apply-templates>,
taking
an XPath expression as its value. However, with <xsl:apply-templates>,
if there are several matches, the relevant templates are instantiated multiple
times. With <xsl:value-of>,
only the first instance is used. Also, unlike with <xsl:apply-templates>,
in this case the attribute is mandatory.
The value of this expression is always written to the result
tree as a string, so some conversion might need to take place first. A number
is converted to the
string representation of that number. If a node contains sub-nodes, the value
is the concatenation of the values of all the sub-nodes. So, for example, for
our document HamletExtract.xml,
we could include within the <SCENE>
template a line:
<xsl:value-of
select="SPEECH[3]"/>
This will return a value that is the concatenation of the
values of the <SPEAKER>
and <LINE>
elements of the third <SPEECH>. This is the speech that will be
selected:
<SPEECH>
<SPEAKER>BERNARDO</SPEAKER>
<LINE>Long live the king!</LINE>
</SPEECH>
So the text returned will be BERNARDOLong
Live the king!.
Finally, if the result is a Boolean, it will be converted to
one of the strings true or false.