Running code with different processors I noticed differences in
processing. In particular, I noticed laxness with duplicate definitions
in LibXSLT and Xalan-J. MSXML is non-conformant when duplicates result
from an xsl:include. Saxon 6.5 is conformant in every respect I tested.
Saxon 9, which is bound by XSLT 2.0, is stricter than required by 1.0.
The spec says in section 17:
A conforming XSLT processor must signal any errors except for those
that this document specifically allows an XSLT processor not to
signal. A conforming XSLT processor may but need not recover from any
errors that it signals.
http://www.w3.org/TR/xslt#conformance
Signaling errors is quite useful, of course; failure to do so has the
potential to hide bugs.
This somewhat lengthy mail presents a number of test cases aiming at
eliciting error messages for duplicate definitions. At the end there
is a small table containing a conformance listing.
I'm posting this here as four (or five) different processors are
involved. (And then point to it on the forums for Xalan and LibXSLT.)
~~~~~~~~
(1) This stylesheet consisting of only one module contains a duplicate
match template:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">eins</xsl:template>
<xsl:template match="/">DUPL</xsl:template>
</xsl:stylesheet>
(2) And so does this stylesheet consisting of two modules:
milu(_at_)colinux:~/Werkstatt/xsl/dupldef > expand -t2 includer.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="lib.xsl"/>
<xsl:template match="/">eins</xsl:template>
</xsl:stylesheet>
milu(_at_)colinux:~/Werkstatt/xsl/dupldef > expand -t2 lib.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">DUPL</xsl:template>
</xsl:stylesheet>
The XSLT 1.0 spec says the following in 5.5 (Conflict Resolution for
Template Rules):
It is an error if [eliminating matching templates based on lower
import precedence and lower priority] leaves more than one matching
template rule. An XSLT processor may signal the error; if it does
not signal the error, it must recover by choosing, from amongst the
matching template rules that are left, the one that occurs last in
the stylesheet.
http://www.w3.org/TR/xslt#conflict
(3) Duplicate named templates:
milu(_at_)colinux:/tmp/dupldef > expand -t2 dupltmpln.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="T">eins</xsl:template>
<xsl:template name="T">DUPL</xsl:template>
<xsl:template match="/"><xsl:call-template name="T"/></xsl:template>
</xsl:stylesheet>
The XSLT 1.0 spec says in section 6:
It is an error if a stylesheet contains more than one template with
the same name and same import precedence.
http://www.w3.org/TR/xslt#named-templates
(4) Duplicate top-level variables:
milu(_at_)colinux:/tmp/dupldef > expand -t2 duplvar.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="var" select="'eins'"/>
<xsl:variable name="var" select="'DUPL'"/>
<xsl:template match="/"><xsl:copy-of select="$var"/></xsl:template>
</xsl:stylesheet>
(5) Duplicate top-level parameters:
milu(_at_)colinux:/tmp/dupldef > expand -t2 duplparm.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="var" select="'eins'"/>
<xsl:param name="var" select="'DUPL'"/>
<xsl:template match="/"><xsl:copy-of select="$var"/></xsl:template>
</xsl:stylesheet>
The spec says in section 11.4:
It is an error if a stylesheet contains more than one binding of a
top-level variable with the same name and same import precedence.
http://www.w3.org/TR/xslt#variables
The title of said section is "Top-level Variables and Parameters". The
quoted statement could be clearer, but it is intended to refer to both
both xsl:variable and xsl:param.
(6) Duplicate namespace alias declarations:
milu(_at_)colinux:~/Werkstatt/xsl/dupldef > expand -t2 duplnsalias.xsl
<xsl:stylesheet version="1.0"
xmlns:aaa="aaa" xmlns:milu="de.milu.test"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="milu"/>
<xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="xsl"/>
<xsl:template match="/">
<aaa:Urmel/>
</xsl:template>
</xsl:stylesheet>
The spec says in section 7.1.1:
If a namespace URI is declared to be an alias for multiple different
namespace URIs, then the declaration with the highest import
precedence is used. It is an error if there is more than one such
declaration. An XSLT processor may signal the error; if it does not
signal the error, it must recover by choosing, from amongst the
declarations with the highest import precedence, the one that occurs
last in the stylesheet.
(7) Duplicate attribute set declarations:
milu(_at_)colinux:~/Werkstatt/xsl/dupldef > expand -t2 duplattrset.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute-set name="a">
<xsl:attribute name="font-size">2em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="a">
<xsl:attribute name="font-size">3em</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<xsl:element name="Urmel" use-attribute-sets="a"/>
</xsl:template>
</xsl:stylesheet>
The spec says in section 7.1.4:
It is an error if there are two attribute sets that have the same
expanded-name and equal import precedence and that both contain the
same attribute, unless there is a definition of the attribute set with
higher import precedence that also contains the attribute. An XSLT
processor may signal the error; if it does not signal the error, it
must recover by choosing from amongst the definitions that specify the
attribute that have the highest import precedence the one that was
specified last in the stylesheet.
(8) Duplicate output attributes:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:output method="xml"/>
<xsl:template match="/"><Elm>Hallo</Elm></xsl:template>
</xsl:stylesheet>
It is an error if there is more than one such value for an attribute.
An XSLT processor may signal the error; if it does not signal the
error, if should recover by using the value that occurs last in the
stylesheet.
~~~~~~~~
Okay. I tested some processors with regard to duplicate definitions as
per the XSLT 1.0 specification and the above examples.
spec XalJ LibX MSXML Sa65 Sa91
(1) match template RE R+ R+ R+ W+ W+
(2) same with xsl:include RE R+ R+ r- RE RE
(3) name template CE CE CE CE CE CE
(4) xsl:variable CE -- CE CE CE CE
(5) xsl:param CE -- -- CE CE CE
(6) xsl:namespace-alias RE r- r- R+ R+ CE
(7) xsl:attribute-set RE R+ r- R+ R+ R+
(8) xsl:output RE R+ R+ R+ R+ CE
Legend:
CE : (spec) non-recoverable compilation error
RE : (spec) recoverable error
W+ : (impl) warning, recovery and correct result
R+ : (impl) recovery and correct result
r- : (impl) recovery and wrong result (bug)
-- : (impl) failure to raise an error (bug)
Versions:
Xalan-J : 2.7.1
LibXSLT : 1.1.24
MSXML6 : 6.0 (I think)
Saxon65 : 6.5.5
Saxon9 : 9.1.0.7J (2.0 processor, only for comparison)
Xalan-J is run with the -QC switch, which should give additional
warnings.
It seems both Xalan-J and LibXSLT are non-conformant for three
cases each: both with respect to xsl:param and xsl:namespace-alias;
Xalan-J with respect to xsl:variable; and LibXSLT with respect to
xsl:attribute-set.
MSXML6 is non-conformant with respect to duplicate definitions involving
an xsl:include; not only named templates, as in the example above, but
also duplicate variables, duplicate parameters and maybe other
constructs.
--
Michael Ludwig
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--