Alain Couthures, AgenceXML
John Boyer, IBM
Leigh Klotz, Xerox (chair, minutes)
Nick van den Bleeken, Inventive Designers
Philip Fennell, MarkLogic
Uli Lissé, DreamLabs [joined late]
Erik Bruchez, Orbeon [joined late]
Alain Couthures: I don't know what
to do about dependencies. For example, could a repeat be applied to
the result of a transformation. Also, submission and
transformation. I saw a tweet about it from betterForm: "as a
special submissionhandler returning the transform results with
replace="instance"
Alain Couthures:
http://betterform.wordpress.com/2011/10/12/aeronautical-information-services-ais-and-xforms/
Nick van: This is about subforms or
transformations?
Alain Couthures: Both.
Leigh Klotz: So they're using a
transform for default values.
Alain Couthures: Yes, we talked about
that some time ago.
Leigh Klotz: They don't say if it's an
action or a function.
Alain Couthures: The tweet says "as
special submissionhandler returning the transform results with
replace="instance""
Leigh Klotz: I guess they do that to
avoid the delete and insert you would have with an action.
Alain Couthures: I'm not doing the
same thing for the same problem.
John Boyer: I was looking at some
uses of eval() in XPath 1.0, as an extension function. I'm looking
at iterating over nodes effectively and generically separating the
algorithm from the details. Sorting is a decent chopping block on
which to try out features. Right now we have a wiki page on eval()
which suggests that the first parameter is an XPath expression to
be evaluated. The note says that Saxon has a similar "evaluate"
function and perhaps we should use that. The Saxon evaluate
function has more parameters, and those parameters are used to feed
XPath variables to the evaluation of the first parameter
expression. The Saxon evaluate says it will receive variables from
the context of the eval function, so it starts with zero variables.
If you provide parameters, those show up as parameters. It was
slightly weird that p1 is the second parameter and p2 is the third,
but it works. I couldn't figure out if there is some compelling
reason why the context variables are not available. I wonder what
the reason would be for the variable not being passed in?
Leigh Klotz: It could be for sanitized
access.
Nick van: Or for using it in different
places; in XSLT you can't change variables, so you can't use
evaluate if the variable is already used.
John Boyer: Right. I thought perhaps
one reason was that you might already have a $p1. On the other
hand, if you're getting variables from the surrounding context, why
would you need those parameters?
Nick van: If you're re-using the
expression, because it's stored in your data.
John Boyer: I see. My use cases are
for an algorithm invoked by dispatch and dynamically construct an
XPath expression for the eval(). Your alternative use case is
dynamically-constructed XPath from instance data, with three
different occurrences of eval() that all consume that
expression.
Nick van: Yes.
John Boyer: It might be preferable to
express it one time.
Nick van: You can't re-define the
variables though.
John Boyer: Yes, creating one action
used from three locations might be preferable.
Nick van: Then your evaluation context
is there.
John Boyer: That's a segue into the
other aspect of this.
John Boyer: I have started to hit
cases with an alternative meaning of the second parameter: the
second optional would be an XPath expression that would identify a
context. In sort, when I want to compare two person
records they might have a first and last name as separate elements.
I'd like to have the key value for a person be concat(last,
first)
. I'd like to call that expression in the context of
two different elements.
Leigh Klotz: It sounds like it could
be a function called evaluate-in-context.
John Boyer: It could. Then we could
still preserve the idea...or our eval function isn't saxon:evaluate
or evaluate.
Leigh Klotz: Don't they have it in
XPath 3? They have serialize.
Nick van: I think they have only parse
and serialize.
John Boyer: It could be a separate
function.
Nick van: A variable and a context
attribute would also work.
John Boyer: In XPath 2 you can call a
function in a location step and return a context, so it's an XPath
1 limitation. In XPath 1 the first location is the only place you
can do the location step; after that first slash has to have a
location-path. On the othe hand if I want a form that will survive
XPath 1.0 - vs 2.0 then I am back to writing it in a way that works
in both. But it is an XPath 1.0 limitation.
Nick van: Leigh's solution is nice; if
it's a function, it can go in the bucket of functions that are
handy in XPath 1.0.
John Boyer: Would it be available only
in XPath 1.0?
Nick van: Probably we could make it in
2.0 but it's in the not-so-useful functions for XPath 2.0, because
there you can use the location-path followed by the function.
John Boyer: So far we had a dividing
line with XPath 2.0 function equivalents being added. In this case,
to do it in XForms with 1.0 or 2.0, you'd need that function in
both.
John Boyer: As a separate function it
would be useful. eval-in-context could take additional parameters
for variables.
Erik Bruchez: [joins]
Nick van: Could you recap for
Erik?
John Boyer: I've been working on
algorithms like sort as a benchmark for iteration and eval. eval
seemeed function for separating the algorithm from the data. To
compare two person records, I want the caller to to provide the
comparison, as is typical. If a person record has a first and last
name, the comparison operation would be concat(last,first) for the
key. So what I wanted was an eval function would work in different
contexts, for the two sort elements: eval(key, element1),
eval(key, element2)
. saxon:evaluate has a first parameter of
an expression, but the rest are variables named $p1, $p2, etc. I
was suggesting a context expression (perhaps not just a node).
Leigh suggested calling that a different function, eval and
eval-in-context.
Leigh Klotz: Did you mean a string?
for context.
Nick van: John wants to write
context-expr/eval($expr)
but this isn't supported in
XPath 1.0
John Boyer: I have to evaluate it once
again as it's passed by a string. It's early stage but I think it's
a context expression.
Nick van: you can't put a function in
the middle of a location path when using xpath 1.0 this feature is
added in XPath 2.0
Nick van: So John wants
eval-in-context($expr, context-expr)
Leigh Klotz: Must it be a string or
would calling eval a second time work? Or does it have "turtles all
the way down" again?
Erik Bruchez: In XPath 3 you could
pass a function to the sort function. Since we don't have XPath 3,
it's not going to look very pretty. Why does the eval function need
a context other than the caller?
John Boyer: The sort action sequence
would call eval.
Erik Bruchez: So you would provide an
expression that points to the person elements, and the key
expression. The sort function or action, would it take the current
element as the context?
John Boyer: A sort action needs to
call something like compare(eval(keyExpr, firstElem),
eval(keyExpr, secondElem))
John Boyer: The caller of the sort
provides keyExpr = concat(last, first)
. This keyExpr
needs to be evaluated in two different contexts. In XPath 2 you can
write firstelem/eval(keyExpr) but that doesn't work in XPath 1. So
we need an algorithm expression that would work in both. Also, this
lets you get around the function call except in the first
step.
Leigh Klotz: Except in
predicates.
John Boyer: That's a location-step as
well. It only filters on matches of node-test or name-test or
similar.
John Boyer: In XPath 2.0
firstelem/eval(keyExpr) produces a String. In XPath 1.0 you can't
get anything but a nodeset.
John Boyer: That's the sales pitch for
a context parameter.
Erik Bruchez: Could we approximate
functions somehow to prepare the way for XPath 3?
Leigh Klotz: eval is already present
as an extension in Xpath 1 in Saxon and shouldn't be too hard to
write. It's not until XPath 3 that we get first-class functions,
which indicates that it may require some thought.
Erik Bruchez: I wonder if we can find
some way around those lines. Eval might not be needed at all. It's
not entirely clear how we could.
Leigh Klotz: I think an
eval(expression, context, param1, param2) may be sufficient to
write the Y combinator, meaning we do have recursive
functions.
Erik Bruchez: sort(expression,
comparator-function-name, etc.)
Name instead of
expression.
Nick van: I know how it's supposed to
work in functional languges but how would you do that in XPath
1?
Erik Bruchez: Function name string.
It's not exposed to the caller. Here: 'sort(instance()/person,
"my-comparator") and <xforms:function
name="my-comparator">...
John Boyer: All they have inside the
function is XPath. So how do you invoke a function?
Erik Bruchez: The user of the sort
function doesn't have to do that. There's the key function and the
compare function.
Nick van: That solves the function for
the sort, but sort was just an example of eval using standard
XForms actions.
John Boyer: sort is a representative
of this kind of processing.
Leigh Klotz: The question is not how
to call a built-in sort function, but how can you write a sort
function as an action.
Erik Bruchez: So you want a different
eval function that takes the context as a parameter?
John Boyer: Yes, I think that would
solve it.
Erik Bruchez: I'm not convinced
saxon:eval can't be improved on. It works in XPath 2. I remember a
couple of year ago when we talked about the function element, Mike
Kay said that XPath 3 they had considered a few options about scope
and the three possibilities were pass context (essentually this),
lexical (where the function is defined), and no context. They chose
no context, I believe. In anonymous functions, there is no initial
context item, but the main point is that you can pass the context
to the function.
Nick van: I think a different name is
a better option.
Leigh Klotz: Does XPath 3 have the
context() function? If so you could pass context() to the function
and use it anywhere, because it doesn't have the location-step
restriction.
Erik Bruchez: No, it doesn't have
context().
Leigh Klotz: Scheme eval() takes the
expression, env.
John Boyer: Could we accept this
proposal to add eval-in-context to our eval proposal, but the
second parameter is the context.
Leigh Klotz: The actual context node,
not a string.
John Boyer: Let me think about
that.
Erik Bruchez: For Saxon, the variables
are kind of funny. It's the dynamic context. There's more than just
the context item. There's also context-item, context-position, and
scope variables. This function would handle only
context-item.
John Boyer: My initial reaction was a
string to get a context, nodeset, size. I don't have any direct
applications for the size component of a nodeset if a nodeset were
provided. That might be a problem for XPath 1 because you have
provide a particular context node anyway, so maybe the second
parameter being the actual node only is the best approach. If you
really need a string, you can focus.
Leigh Klotz: Erik, can you live with
it?
Erik Bruchez: Yes, I can.
Resolution 2011-10-12.1: We add eval-in-context to our eval proposal, but the second parameter is the context node.
ACTION-1836 John Boyer to add eval-in-context to our eval proposal, but the second parameter is the context node.