Recipe6.5.Avoiding 1.0 to 2.0 Porting Pitfalls


Recipe 6.5. Avoiding 1.0 to 2.0 Porting Pitfalls

Problem

Not every 1.0 stylesheet will work transparently in 2.0.

Solution

If you need to port 1.0 stylesheets to 2.0, you will want to watch out for several gotchas. Some of these problems can be eliminated by using XSLT 1.0 compatibility mode; that is, by using version=1.0 in the stylesheet element, <xsl:stylesheet version="1.0">. However, if you want to begin migrating old stylesheets to 2.0, there are other solutions to these incompatibilities, as explained next.

XSLT 2.0 processors are not obligated to support backward compatibility mode, although most probably will. If it is not supported, the processor will signal an error.


Sequences do not transparently convert to atomic items

Consider the fragment <xsl:value-of select="substring-before(Name, ' ')"/>. What happens if this is evaluated in a context that includes more than one Name element? In XSLT 1.0, only the first one would be used, and the rest would be ignored. However, XSLT 2.0 is stricter and signals a type error because the first argument if substring-before can only be a sequence of 0 or 1 strings.

To remedy this, you should get in the habit of writing <xsl:value-of select="substring-before(Name[1], ' ')"/>. On the other hand, you may want to know about these errors because they might signal a bug in the way the stylesheet or its input documents are written. An alternative fix, which may be applicable in some circumstances, is to combine multiple nodes into a single node before presenting the sequence to a function expecting only one. For example, <xsl:value-of select="substring-before(string-join(Name), ' ')"/> would not generate an error.

Types do not transparently convert to other types

XSLT 1.0 was very lax when it came to type conversions. If a function expected a number and you provided a string, it would do its best to convert the string to a number and visa versa. The same applied to conversions among Boolean and integer or Boolean and string. The old behavior can be preserved by using 1.0 compatibility mode. However, you can also explicitly convert values:

    <xsl:variable name="a" select=" '10' "/>     <xsl:value-of select="sum($a, 1)"/> <!-- Error -->     <xsl:value-of select="sum(number($a), 1)"/> <!-- OK -->     <xsl:value-of select="string-length(10)"/> <!-- Error -->     <xsl:value-of select="string-length(string(10))"/> <!-- OK -->     <xsl:value-of select="string-length(string(true( )))"/>                                                     <!-- OK, equals 4 -->     <xsl:value-of select="1 + true( )"/> <!-- Error -->     <xsl:value-of select="1 + number(true( ))"/> <!-- OK, equals 2 -->

Extra parameters are not ignored

In XSLT 1.0, if you invoked a template with xsl:call-template passed parameters that the template did not define, the extra parameters were silently ignored. In 2.0, this is an error. You can disable this error by using 1.0 compatibility mode. There is no other work around, except removing the extra parameters or introducing defaults into the existing template.

Stricter semantic checking will cause errors on questionable usage

Examples of this can be seen in both the xsl:number and xsl:template instructions. If you use level and value attributes together in xsl:number, the level attribute is ignored in 1.0, but this is an error in 2.0. Similarly, with xsl:template, you cannot specify priority or mode in 2.0, if there is no match attribute defined.

Discussion

Use of backward-compatibility mode to correct errors in 1.0 stylesheets has other consequences. In particular, it means that some things will behave differently. In 1.0 compatibility mode:

  • xsl:value-of will output only the first item of a sequence rather than all items separated by spaces.

  • an attribute value template (e.g. <foo values="{foo}"/>) will output only the first item of a sequence rather than all items separated by spaces.

  • the first number in a sequence will be output rather than all numbers separated by spaces when using xsl:number.

    For these reasons, it would be wise not to rely on backward-compatibility mode for new stylesheet development intended to target a 2.0-compliant processor.




XSLT Cookbook
XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition
ISBN: 0596009747
EAN: 2147483647
Year: 2003
Pages: 208
Authors: Sal Mangano

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net