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 29374 - fn:transform
Summary: fn:transform
Status: CLOSED WORKSFORME
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: Functions and Operators 3.1 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Linux
: 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: 2016-01-14 00:22 UTC by Benito van der Zander
Modified: 2016-03-22 09:40 UTC (History)
2 users (show)

See Also:


Attachments

Description Benito van der Zander 2016-01-14 00:22:56 UTC
It is strange that in XQuery the function to load an xquery module has the long name fn:load-xquery-module, but the function to run an xsl transformation has the short name fn:transform. After all, when you write XQuery, XQuery is already implicitly used, so you rather expect a short fn:load-module or even just fn:module. While XSLT is an entire different language, so it seems more logical to have fn:run-xslt or fn:xsl-transform. Seems it was heavily influenced by a XSLT working group, but it is an XPath function, not an XSLT function...

I hope a standalone XQuery processor is not required to support fn:transform.


And unfortunately I already have a custom transform function in my implementation.
Defined as 

pxp:transform($root as item()*, $f as function(*), $options as map()) as item()*){
 for $i in $root return $f($i)!(if (. instance of node() and ( . is $i or $options("always-recurse") ) ) then (
                 typeswitch (.)
                   case element() return element {node-name(.)} { @* ! $f(.), node()!pxp:transform(., $f, $options) }
                   case document-node() return document {  node() ! pxp:transform(., $f, $options) }
                   default return .
              ) else . )
}              
pxp:transform($root as item()*, $f as function(*)) as item()* { pxp:transform($root, $f, {}) }
pxp:transform($f as function(*)) as item()* { pxp:transform(., $f, {}) }


That is quite useful to perform a map/filter over all nodes in a document. 
E.g. For example transform(/, function($x) { if (name($x) = "a") then <a>{$x/@*, <b>{$x/node()}</b>}</a> else $x } ) to make all a-links bold; or  transform(/, function($x) { if (name($x) = "a") then () else $x } ) to remove them.
Comment 1 Michael Kay 2016-01-14 10:15:15 UTC
Can't really comment on the name; these things happen. Some of us like short names, some like long names, but we all hate meetings where a lot of time is spent on deciding the best terminology. The function names evolved as their specification evolved: the original idea was to have something that dynamically executed a query, but we decided that dynamically loading a query and making its functions available for execution was much more powerful, so the name changed to reflect this.

I believe the current state of the conformance rules is that a query processor is required to recognize the fn:transform function, but it is allowed to throw a dynamic error if "no suitable XSLT processor is available". This means queries can be made interoperable provided they are written using try-catch.
Comment 2 Abel Braaksma 2016-01-14 12:08:03 UTC
Naming is always tricky, but there's a big difference here. The fn:load-query-module loads a module and exposes its functions, but does *not* execute it. The fn:transform actually invokes a transformation, but does *not* make its functions available (this does, however, beg the question: why can't we load an xslt module or package?).

Your argument suggests that because you are "already in XQuery, it should be a short name". But these are XPath Functions and Operators shared between multiple languages, fn:load-query-module is therefore also available from XSLT and any other language or environment that exposes F&O.

Since the words load or load-module could mean multiple things, I think the WG made a good decision here. Likewise, transform is a verb used primarily with XSLT, so the added prefix "xsl" seems redundant.

The function was added by the joined WG's, only recently they asked the XSL WG to update the spec such that it reflected the new state the XSLT spec is in. It seems only reasonable that if in F&O you add a function for XQuery, you also add something for XSLT, as both are the prime languages where F&O is used in.

Whether or not an XQuery processor supports the fn:transform function or an XSLT processor supports the fn:load-query-module function is highly dependent on the implementations and yes, this may mean that such an implementation allows you to configure an external, extra xquery/xslt processor for this task.
Comment 3 Andrew Coleman 2016-01-21 11:29:54 UTC
The WGs discussed this at the Joint WG teleconference on 2015-01-19 and agreed to keep these function names unchanged.

Many thanks for the discussion.