Hi, Andy.

Andy Chambers <achambers.h...@googlemail.com> wrote on 2009-02-06 05:24:42 
AM:
> Consider the following stylesheet....
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="1.0"
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>   xmlns:str="http://exslt.org/strings";>
> 
>   <xsl:template match="/">
>    <root>
>      <xsl:choose>
>       <xsl:when test="function-available('str:tokenize')">
>                   <!-- called when run by xalan -->
>         <xsl:value-of select="str:tokenize('date math str')"/>
>       </xsl:when>
>       <xsl:otherwise>
>                   <!-- called when run by saxon -->
>         <xsl:value-of select="tokenize('date math str')"/>
>       </xsl:otherwise>
>      </xsl:choose>
>    </root>
>   </xsl:template>
> 
> </xsl:stylesheet>
> 
> My specific problem is that saxon supports the use of XSLT2's tokenize
> which is supported in xalan using the exslt str extension.
> 
> I need my stylesheet to work in both and my plan was to use
> function-available('str:tokenize') to determine which one to use.  The
> problem is that even though xalan wouldn't enter the second branch, it
> detects that it can't call tokenize and throws the following
> error.
> 
> SystemId Unknown; Line #15; Column #55; Could not find function: 
tokenize
> SystemId Unknown; Line #15; Column #55; function token not found.
> (Location of error unknown)java.lang.NullPointerException

XSLT 1.0 is a bit vague on how references to unknown functions that are in 
no namespace should be handled.  Section 2.5 on Forwards-Compatible 
Processing[1] states, "If an expression occurs in an attribute that is 
processed in forwards-compatible mode, then an XSLT processor must recover 
from errors in the expression as follows: ...  if the expression calls a 
function with an unprefixed name that is not part of the XSLT library, 
then an error must not be signaled unless the function is actually 
called."  So this seems to imply that the processor should raise an error 
for the reference to tokenize when not in forwards-compatible mode, but 
the recommendation never actually comes out and states that explicitly 
anywhere.

Having said that, Xalan-Java has a bug and still reports that same error 
when the stylesheet is processed in forwards-compatible mode (i.e., the 
version attribute on the xsl:stylesheet element has the value "2.0".) 
However, Xalan-J does not have this same problem with extension functions 
- the processor will only report an error for an extension function that 
it does not recognize if it attempts to evaluate the function.  The 
functions in XSLT 2.0 and XPath 2.0 are actually in a namespace that's 
used implicitly by an XSLT 2.0 processor, but the namespace can be made 
explicit in an XSLT 2.0 stylesheet.  So, if you change your stylesheet to 
explicitly use that namespace on the reference to the tokenize function, 
it will appear to Xalan-J as an extension function.

The following stylesheet should work with Xalan-Java:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:fn="http://www.w3.org/2005/xpath-functions";
  xmlns:str="http://exslt.org/strings";>

  <xsl:template match="/">
                 <root>
                   <xsl:choose>
                                 <xsl:when 
test="function-available('str:tokenize')">
                  <!-- called when run by xalan -->
                                   <xsl:value-of 
select="str:tokenize('date math str')"/>
                                 </xsl:when>
                  <!-- called when run by saxon -->
                                 <xsl:otherwise>
                                   <xsl:value-of select="fn:tokenize('date 
math str')"/>
                                 </xsl:otherwise>
                   </xsl:choose>
                 </root>
  </xsl:template>
 
</xsl:stylesheet>

I hope that helps.

Thanks,

Henry
[1] http://www.w3.org/TR/xslt#forwards
------------------------------------------------------------------
Henry Zongaro
XML Transformation & Query Development
IBM Canada Lab   T/L 313-6044;  Phone +1 905 413-6044
mailto:zong...@ca.ibm.com

Reply via email to