This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 30049 - [XSLT30] Request for clarification if xsl:evaluate example supposed to implement function-lookup is supposed to return empty sequence if function is not found
Summary: [XSLT30] Request for clarification if xsl:evaluate example supposed to implem...
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-01-16 11:44 UTC by Martin Honnen
Modified: 2017-01-27 10:56 UTC (History)
0 users

See Also:


Attachments

Description Martin Honnen 2017-01-16 11:44:33 UTC
https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/Overview-diff.html#evaluate-examples has an example saying

----------------------------------------------------------------------
The function-lookupFO30 function, if it were not available in the standard library, could be implemented like this:

<xsl:function name="f:function-lookup">
       <xsl:param name="name" as="xs:QName"/>
       <xsl:param name="arity" as="xs:integer"/>
       <xsl:evaluate xpath="'Q{' || namespace-uri-from-QName($name) || '}' 
                      || local-name-from-QName($name) || '#' || $arity">
         <xsl:with-param name="name" as="xs:QName" select="$name"/>
         <xsl:with-param name="arity" as="xs:integer" select="$arity"/>
       </xsl:evaluate>
     </xsl:function>  
     

The xsl:evaluate instruction uses the supplied QName and arity to construct an expression of the form Q{namespace-uri}local#arity, which is then evaluated to return a function item representing the requested function. 

--------------------------------------------------------------------------

However, the FO30/31 'function-lookup' https://www.w3.org/TR/xpath-functions-30/#func-function-lookup has the signature fn:function-lookup($name as xs:QName, $arity as xs:integer) as function(*)? and is defined to return an empty sequence if the function is not found: "Otherwise (if no known function can be identified by name and arity), an empty sequence is returned".

As far as I can tell and have tested, above example of using xsl:evaluate inside of the function declaration of 'f:function-lookup' will return an error XTDE3160 if the function is not found so in that case it is not an implementation of 'function-lookup' and behaves differently.

So I think either the explanation should say that 'f:function-lookup' behaves slightly differently or the function implementation needs to be fixed to

	<xsl:function name="f:function-lookup">
		<xsl:param name="name" as="xs:QName"/>
		<xsl:param name="arity" as="xs:integer"/>
		<xsl:try>
            <xsl:evaluate xpath="'Q{' || namespace-uri-from-QName($name) || '}' 
                || local-name-from-QName($name) || '#' || $arity">
                <xsl:with-param name="name" as="xs:QName" select="$name"/>
                <xsl:with-param name="arity" as="xs:integer" select="$arity"/>
            </xsl:evaluate>
            <xsl:catch errors="err:XTDE3160" select="()"/>
		</xsl:try>
	</xsl:function>
Comment 1 Michael Kay 2017-01-16 23:42:19 UTC
Certainly we should fix the example. I think it's dangerous to try and write an example and claim that its effect is precisely equivalent to fn:function-lookup(); I think it's safer to leave the example "as is" and qualify the claim of equivalence: 

"If the function-lookupFO30 function were not available in the standard library, then a very similar function could be implemented like this:"

... "Note: this differs from the effect of fn:function-lookup() in that it raises an error when the function does not exist, rather than returning an empty sequence."

The related discussion on the mulberrytech xsl-list and on https://saxonica.plan.io/issues/3109 appears to raise another point, however.

Under xsl:evaluate (§10.4.2) we say: "All other aspects of the dynamic context are the same as the dynamic context for the xsl:evaluate instruction itself, except ..."

and this presumably includes "named functions". But the dynamic context for xsl:evaluate is defined by §5.3.3, and this omits to tell us how the dynamic context component "named functions" is initialised. For example, does it include stylesheet functions with visibility="private"?

* If such functions are excluded, then we break the rule in XPath that the functions in the dynamic context always include all the functions in the static context

* If such functions are included, then we have a strange inconsistency with the statement that the static context for the evaluation of the XPath expression supplied to xsl:evaluate excludes these functions.

Similarly, does it include XSLT-defined functions such as fn:document()? It seems a little odd that these are available to calls on fn:function-lookup(), but not available to calls on xsl:evaluate - except of course that the reason we excluded them from xsl:evaluate is to allow a free-standing third-party XPath parser to be used.

Concerning §5.3.3, we should note also:

* the dynamic context component previously called "dynamic variables" is now called "variable values"

* there are new components "default language", "default calendar", "default place", "available text resources", "available uri collections", "default uri collection", "environment variables".

It seems best to handle these with a catch-all addition: "Other components of the dynamic context are initialized as described in the [XPath 3.0] specification (or [XPath 3.1], where supported).

I also note that in §5.3.3 the link rendered as "available collections" is actually a link to the anchor "dt-known-collections" in XP30, but there is no such anchor (the actual anchor is dt-available-collections). It's not clear to me why the build system allows the link to be created without error (or, for that matter, why it passes W3C link checking). Similarly, the link rendered as "available documents" has anchor "dt-known-docs" whereas the actual anchor is "dt-available-docs".

Summary of Recommendations (more detailed wording above):

1. Fix the example by withdrawing the claim that the behavior is the same as fn:function-lookup()

2. Fix the gaps in the specification of the dynamic context by saying that other components of the dynamic context are defined as in the XPath spec.

3. (Editorial) Investigate why broken links to the XPath 3.0 specification are not being detected by the build system, and fix the links that are broken.
Comment 2 Michael Kay 2017-01-16 23:50:00 UTC
Actually the targets "dt-known-docs" and "dt-known-collections" do exist, but they are the wrong targets: they refer to the statically known documents and collections, rather than "available documents" and "available node/resource collections". This is also complicated by the fact that "available node collections" in XPath 3.0 is replaced by "available resource collections" in XPath 3.1.
Comment 3 Michael Kay 2017-01-27 10:56:32 UTC
The WG reviewed the bug and agreed with the proposed changes.

I have applied the following changes:

(a) change the example to catch XTDE3160 and return () if the function is unknown.

(b) withdraw the assertion that the function has exactly the same effect as fn:function-lookup, and add the note: "The main difference between this function and the standard fn:function-lookup function is that there are differences in the functions that are visible: for example fn:function-lookup gives access to user-defined functions with private visibility, whereas xsl:evaluate does not.

(c) I have added to 5.3.3.2 (additional components of the dynamic context) the entry:

The *named functions* (representing the functions accessible using function-available or function-lookup include all the functions available in the static context, and may also include an additional implementation-defined set of functions that are available dynamically but not statically.
                        
Note: This set therefore includes some functions that are not available for dynamic calling using <elcode>xsl:evaluate</elcode>, for example stylesheet function whose visibility is private, and XSLT-defined functions such as current and key.

Note: The rule that all functions present in the static context must always be present in the dynamic context is a consistency constraint. The effect of violating a consistency constraint is implementation-defined: it does not necessarily lead to an error. For example, if the version of a used package that is available at evaluation time does not include all public user-defined functions that were available in the version that was used at analysis time, then a processor <rfc2119>may</rfc2119> recover by signaling an error only if the function is actually called. Conversely, if the evaluation-time version of the package includes additional public functions, these may be included in the dynamic context even though they were absent from the static context. Thus dynamic calling of functions using function-lookup may be an effective strategy for coping with variations between versions of a library package on which a stylesheet depends.

(d) Also in 5.3.3 I have added the catch-all: "All other aspects of the dynamic context (for example,the current date and time, the implicit timezone, the default language, calendar, and place, the available documents, text resources, and collections, and the default collection &mdash; details vary slightly between XPath 3.0 and XPath 3.1) are implementation-defined, and do not change in the course of a single transformation." and I have deleted the existing entries which this rule subsumes (current-date-time, implicit-timezone, collections).

(d) In 10.4.2 (dynamic context for xsl:evaluate) I have added the same rule as in (c), but without the notes.

(e) In the existing note in 10.4.2 I have changed "document" to "collection" in the list of example functions whose use may be restricted, because the "document" function is not available in xsl:evaluate.