Bug 17206 - Making dynamic evaluation via xsl:evaluate more dynamic
Summary: Making dynamic evaluation via xsl:evaluate more dynamic
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Working drafts
Hardware: All All
: P2 enhancement
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
Depends on:
Reported: 2012-05-26 20:45 UTC by Jakub Maly
Modified: 2013-02-15 10:52 UTC (History)
0 users

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Maly 2012-05-26 20:45:34 UTC
The new instruction evaluate allows for dynamic evaluation of expressions in stylesheets. 

<xsl:evaluate xpath="'1 + 1'">
Returns 2

All variables in the evaluated expression must be bound using with-param, like in
<xsl:evaluate xpath="'$p1 + $p2'">
  <xsl:with-param name="p1" select="1" />
  <xsl:with-param name="p2" select="2" /> 
</xsl:evaluate> Which returns 3. 

The syntactic rules for with-param are I think the same as in the case of call-template. Aren't those unnecessarily restrictive in this case? 
I suppose (please correct me, if I am wrong) the cost of dynamic evaluation would not change much, if attribute value template was allowed for the attribute name of with-param in evaluate, such e.g.: 
<xsl:evaluate xpath="'$p1 + $p2'">
  <xsl:with-param name="{'p' || '1'}" select="1" />
  <xsl:with-param name="{'p' || '2'}" select="2" /> 

Did this question arise when semantics of evaluate was discussed? 
I have encountered a situation where this would come in handy (well, it would provide an alternative solution to a problem which I solved differently), so maybe those applications that require dynamic evaluation would appreciate it as well. I was a bit surprised that it is not possible, because it feels appropriate to me. When dealing with dynamic evaluation, why not let the names of variables to by dynamic as well? 

Jakub Maly.  
Comment 1 Michael Kay 2012-07-27 20:11:48 UTC
We can see the use case and we're thinking about it.

Note that there is a workaround: rebind the variable names within the expression

<xsl:evaluate xpath="let $xyz := $p1 return
                                  let $qpr := $p2 return
                                  || $expression">
  <xsl:with-param name="p1" select="1" />
  <xsl:with-param name="p2" select="2" /> 

I think my main reluctance with the suggestion as written is that it will encourage people to want all variable names to be dynamic throughout the language.
Comment 2 Michael Kay 2012-07-30 08:07:32 UTC
Further ideas on this in


Comment 3 Michael Kay 2012-09-26 23:43:45 UTC
In response to WG discussion, my proposal as editor is that we satisfy this requirement by removing the xsl:with-param child of xsl:evaluate, and replacing it with a new optional attribute with-params whose value is an expression; the expression must evaluate to a map. The map must be of type map(xs:QName, item()*).

The names present in the map are added to the static context for the target XPath expression, and the name/value pairs present in the map are added to the variable values in the dynamic context of the expression.

It was suggested in the email that we allow any function, not only a map. However, the XPath evaluation model requires variable names to be known statically (i.e at the time of static analysis of the XPath expression, which is during dynamic evaluation of the stylesheet...), and this would not be possible with a general function; we need the ability to enumerate the keys. (Also, from practical experience, the JAXP XPath interface doesn't allow static enumeration of the supplied parameters, and it's a pig to implement as a result)

Unlike the previous xsl:with-param syntax, using a map gives no ability to declare the types of the values, and therefore to get any of the implicit conversions that occur with the function conversion rules. However, we're dealing here with a very dynamic capability, so dynamic typing seems appropriate. A user who wants to have some type checking and implicit conversion can write something like:

<xsl:variable name="p1" select="expression" as="xs:integer"/>
<xsl:evaluate xpath="$p1 + 1" with-params="map{QName("p1") := $p1}"/>
Comment 4 Michael Kay 2012-09-27 16:22:49 UTC
This proposal was accepted.
Comment 5 Michael Kay 2012-09-27 16:27:42 UTC
After I hit SEND to bang the gavel on this decision, the WG changed its mind and decided to keep the old mechanism alongside the new, at least for the time being.
Comment 6 Michael Kay 2013-02-15 10:52:50 UTC
The decision in comment #5 is reflected in the current draft.