Search code examples
xslt-1.0saxonrenderx

saxon complains about unknown function although function-available


I'm transforming something by xslt, trying to make use of the xalan function document-location if and when it is available, and avoiding it otherwise (portable). Sample code:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="function-available('document-location')">
        <xsl:message>YES document-location&#xa;</xsl:message>
        <xsl:message><xsl:value-of select="document-location()"/></xsl:message>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>NO document-location&#xa;</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:transform>

Saxon reports

SAXON 6.5.5 from Michael Kay
Java version 1.7.0_151
Error at xsl:value-of on line 8 of file:minisax.xsl:
  Error in expression document-location(): Unknown system function: document-location
Transformation failed: Failed to compile stylesheet. 1 error detected.

although the function-available test before.trying to use it. It seems to try to use it before "control" would reach that point.

It works correctly with xalanj (well that's easy) but also xsltproc.

How can I make this work?

Edit/Backgroud

That is the saxon version shipped with my Renderx XEP evaluation and makes it difficult to write portable stylesheets to work out-of-the-box. I understand it's not a current saxon issue due to the ancient version.


Solution

  • Saxon 6.5.5 is a very ancient release and I would recommend you move to something more modern. The stylesheet appears to work as expected with Saxon 9.9.

    I'm not going to investigate the Saxon 6.5.5 source code, but one possibility is that it makes the assumption that the spec doesn't allow you to add functions to the default (system-defined) function namespace, and therefore it can assume statically that it knows which functions exist in that namespace. Xalan has apparently broken this rule by adding a non-standard function to the system namespace, and Saxon wasn't reckoning on that.