1

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.

Stefan Hegny
  • 2,107
  • 4
  • 23
  • 26
  • I think you're making the wrong assumption here. When I test the expression `function-available('document-location')` using Saxon 6.5.5, I get the result of `false`: http://xsltransform.net/pNEhB3f – michael.hor257k Mar 12 '19 at 00:08
  • And I get the same result using libxslt (xsltproc). – michael.hor257k Mar 12 '19 at 00:11
  • That may be right, but the error may be thrown before it testing the "function-available" if the function is used inside of the condition. – Stefan Hegny Mar 12 '19 at 07:14
  • 1
    That doesn't mean that the function is available. It suggests that the stylesheet is checked for errors before *anything* is executed. – michael.hor257k Mar 12 '19 at 08:23

2 Answers2

1

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.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Thanks a lot @michalkay! Actually it was not my choice but it is shipped with my Renderx XEP evaluation. And I suspected something about the fact it not being a "real extension function" – Stefan Hegny Mar 11 '19 at 22:35
  • 1
    In fact, I checked the XSLT 1.0 spec of function-available(), and it says " If the expanded-name has a non-null namespace URI, then it refers to an extension function; otherwise, it refers to a function defined by XPath or XSLT. – Michael Kay Mar 12 '19 at 09:13
  • 1
    Furthermore, XSLT 1.0 says "the function library consists of the core function library together with the additional functions defined in [12 Additional Functions] and extension functions as described in [14 Extensions]; it is an error for an expression to include a call to any other function". So Saxon is quite correct to report an error here, given that "extension functions" by definition have a colon in their name. – Michael Kay Mar 12 '19 at 09:16
  • So the error in fact is on the xalanj side in introducing an "extension function" without colon/namespace... or on the side of those trying to make use of it – Stefan Hegny Mar 12 '19 at 09:50
0

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.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • No, I'm on xslt 1.0 and meant the xalanj function document-location, but which is not a real extension function as Michael states. Thanks! – Stefan Hegny Mar 11 '19 at 22:36