Recipe 6.11. Understanding the New Capabilities of Old XSLT 1.0 Features
Problem
There are numerous little enhancements in XSLT 2.0, and it is
difficult to get a quick handle on all of them.
Solution
Many of the capabilities in 2.0 are delivered as enhancements to
existing 1.0 instructions and functions. These are not as obvious as
those that are packaged as completely new instructions or functions.
This section provides a one-stop overview of these enhancements.
xsl:apply-templates
The mode attribute can take the value
#current to signify that the processing should
continue with the current mode. You can take advantage of support for sequences by writing a
comma-separated list (e.g., <xsl:apply-templates
select="title, heading,
para"/>
)
when you want to process title elements first, then heading elements,
and then para elements. In 1.0, you had to write three separate
apply-template instructions. |
In both 1.0 and 2.0, you can write:
<xsl:apply-templates select="title | heading | para"/>
but this is an unordered application. The child nodes will be
processed as they appear in the document and not as you order them in
the select.
|
|
xsl:attribute
A big pet peeve of many XSLT 1.0 developers was the inability to
write <xsl:attribute name="foo"
select="10"/> since the select attribute was not
supported. Now it is supported, and you should prefer it when
defining simple attributes, although the sequence constructor syntax
is still available. The attributes
type and validation were added
in support of schema-aware processors. Type is used to specify native
or user-defined types defined by W3C schema. Validation is used to
specify how the attribute should be validated.
xsl:call-template
The result of the
call
can be an arbitrary sequence (such as a sequence of integers) rather
than just a node set. You will get an error if you supply a parameter (via
xsl:with-param) that the called template does not
define.
xsl:comment
xsl:copy and xsl:copy-of
A new attribute, copy-namespaces="yes
| no", is available to specify
whether the namespace nodes of
an element should be copied. The default is yes,
which is consistent with 1.0 behavior. The attribute type was added to specify native or
user-defined types defined by W3C Schema. The attribute validation was added to specify how
the result should be validated or whether existing type annotations
should be preserved.
xsl:element
xsl:for-each
Can now process
arbitrary
sequences in addition to sequences of nodes: <xsl:for-each select="(1, 2, 3, 4, 5)">
<xsl:value-of select="."/><xsl:text>)
</xsl:text>
</xsl:for-each>
xsl:key
The match and use attributes
can now refer to global variables, provided there is no circularity
between the value of the variables and the key: <xsl:variable name="state" select=" 'active' "/>
<xsl:key name="state-key" match="employee[@state=$state]" use="@type"/>
The use attribute can be replaced by the value of
a sequence constructor: <!--defining the value of a key using some sophisticated processing -->
<xsl:key name="sick-key" select="employee">
<xsl:apply-templates select="record[@type='sick-day']" mode="sick-key"/>
</xsl:key>
xsl:message
The terminate
attribute
can now be an attribute value template. This greatly simplifies
global changes to the termination behavior. A select attribute is now supported in addition to
the sequence constructor form: <xsl:param name="terminate" select=" 'no' "/>
<xsl:template match="employee">
<xsl:if test="not(@type)">
<xsl:message terminate="{$terminate}"
select=" 'Missing type attribute for employee' "/>
<xsl:if>
</xsl:template>
xsl:number
A select attribute has been
added
to allow nodes other than the context node to be numbered. Formatting options have been enhanced to allow output as a word such
as "one",
"two",
"three" according to the chosen
language: <-- This outputs 'Ten' -->
<xsl:number value="10" format="Ww"/>
<-- This outputs 'ten' -->
<xsl:number value="10" format="w"/>
<-- This outputs 'TEN' -->
<xsl:number value="10" format="W"/>
xsl:output
Can be given a name
so that it can be used with the new
xsl:result-document instruction. See Recipe 6.10 for details. A new method, XHTML, is supported. A new attribute, escape-uri-attributes, determines
whether URI attributes in HTML and XHTML output should be escaped. A new attribute, include-content-type, determines
if a <meta> element should be added to the
output to indicate the content type and encoding. A new attribute, normalize-unicode, determines if
Unicode characters should be normalized. See http://www.w3.org/TR/2002/WD-charmod-20020430/
for further details on normalization. A new attribute, undeclare-namespaces, determines
if namespaces in XML 1.1 should be undeclared when they go out of
scope. A namespace is undeclared by
xmlns:pre="",
where pre is some prefix. A new attribute, use-character-maps, allows you to
provide a list of names of character maps. See Recipe 6.8.
xsl:param
An as attribute can
be
used to specify the type of the parameter. A required attribute can be used to specify
whether the parameter is mandatory or optional. A tunnel attribute is used to indicate whether
tunneling is supported for this parameter. See Recipe 6.6.
xsl:processing-instruction
xsl:strip-space
xsl:stylesheet
A new
default-validation
attribute determines the default validation to use when new element
and attribute nodes are created and the instruction that creates them
lacks a validation attribute. A new xpath-default-namespace attribute determines
the namespace used for unprefixed element names in XPath expressions.
xsl:template
Multiple modes are supported
via #all or list of modes in the
mode attribute. An as attribute allows the result type to be
specified. The match attribute supports matching on types. The match attribute can reference global variables
or parameters.
xsl:value-of
xsl:variable
xsl:with-param
An as attribute can be used
to
specify the type of the parameter. A tunnel attribute is used to indicate whether
tunneling is supported for this parameter. See Recipe 6.6. Can now be used with xsl:apply-imports and the new
xsl:next-match instruction. See Recipe 6.6.
current( )
The function can return
generalized items (such as a string) in
addition to nodes. Can now be used within a match pattern to refer to the element that
matched.
<!-- Match nodes with descendant elements that have an attributes whose
value matches the local name matched element -->
<xsl:template match="*[descendant::*/@* = local-name(current( ))]">
document( )
function-available( )
key( )
system-property( )
An xsl:product
property is defined to return the name of
the XSLT processor (e.g., Saxon). An xsl:product-version property is defined to
return the version of the XSLT processor (e.g.,
8.1). An xsl:is-schema-aware property is defined to
return yes or no to indicate if
the processor is schema aware. An xsl:supports-serialization property is defined
to return yes or no to indicate
if the processor supports serialization. An xsl:supports-backwards-compatibility property
is defined to return yes or no
to indicate if the processor supports backward-compatibility mode
(e.g.,
version="1.0").
Discussion
The main themes that govern the new capabilities of old XSLT
instructions are type support and consistency. Here consistency
largely means support for a select attribute when
only a sequence constructor was supported in the past or visa versa.
|
One quirk of the XSLT creators is that they continue to introduce two
distinct names for constructs where, to my way of thinking, one would
have sufficed. In particular, consider the attributes
as and type. They are never
used together, so why not just type? A similar
argument could have been made for eliminating
xsl:with-param in favor of just
xsl:param when 1.0 was specified.
|
|
|