saxon complains about unknown function although function-available

735 Views Asked by At

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.

2

There are 2 best solutions below

4
On BEST ANSWER

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.

1
On

I tested it with the current version of xsltproc and the result is NO. This probably occurs due to the fact that there is no document-location() function in XSLT.

Hence I guess that you did mean the document-uri() function which is available in XSLT 2.0 and above.

So if you change your XSLT to

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

you will get a positive 'YES' result from Saxon and the path of the current XML document.

P.S.: Your Saxon version is ancient.