- From: John Boyer <boyerj@ca.ibm.com>
- Date: Mon, 31 Oct 2011 06:57:26 -0700
- To: public-forms@w3.org
- Message-ID: <OF1F7EF1D6.7AF109CF-ON8825793A.004BA6DB-8825793A.004CAECD@ca.ibm.com>
Hi everyone,
I'm pretty sure Erik briefly raised this when we spoke about iterate, but
the conversation moved on without our fully digging into this...
Since we're adding the context attribute everywhere and also adding the
iterate attribute to optimize data iteration action sequences, we really
ought to repair the context attribute as applied to the insert and delete
actions in XForms 1.1.
The problem is that the context attribute should only perform the first
function below, but it is performing both:
1) override the default in-scope evaluation context
2) provide the parent of the nodeset in which to insert if the nodeset is
empty
The latter function should be controlled by a second attribute, perhaps
named "parent".
Without this change, it is either impossible or hard to understand the
impact of the context attribute on function #2 above when used in
combination with the iterate attribute.
Note that the context attribute is evaluated first for all elements and
overrides the in-scope evaluation context used in other attributes,
including iterate, while and if.
As an example, I'd like to be able to reverse the nodes of a list with an
action sequence along the lines of this:
<xforms:action ev:event="custom-reverse">
<xforms:insert context="some/list" iterate="*" origin="."/>
<xforms:delete nodeset="some/list/*[position()*2 > last()]"/>
</xforms:action>
The first line obtains the parent node of some list, then iterates its
children and prepends each to the front of some/list. While this *could*
work, I think it shouldn't. The iterate attribute will repeat an action,
except for its context and iterate attributes, so I think the iterated
insert action has neither an expressed context nor an expressed nodeset
attribute. I think I should have to use this:
<xforms:action ev:event="custom-reverse">
<xforms:insert context="some/list" iterate="*" parent=".."
origin="."/>
<xforms:delete nodeset="some/list/*[position()*2 > last()]"/>
</xforms:action>
One can attempt to reverse the order of evaluationg iterate and context
using an action element nesting, like this:
<xforms:action ev:event="custom-reverse">
<xforms:action iterate="some/list/*">
<xforms:insert context=".." origin="???"/>
</xforms:action>
<xforms:delete nodeset="some/list/*[position()*2 > last()]"/>
</xforms:action>
But, one can no longer use origin="." because the context attribute resets
the meaning. Nor can one use origin="context()" because the context
attribute resets that, too. One is therefore forced to use a nodeset
attribute instead, like this:
<xforms:action ev:event="custom-reverse">
<xforms:action iterate="some/list/*">
<xforms:insert nodeset="../*" at="1" position="before" origin="."/>
</xforms:action>
<xforms:delete nodeset="some/list/*[position()*2 > last()]"/>
</xforms:action>
One ugly aspect of this insert is that its nodeset attribute will match
all of the original N nodes (plus all the inserted ones) for each of the N
inserted nodes, so you get O(N^2) performance. Now, you can add [1] to
the nodeset attribute and then cross a small army of fingers and toes with
the hope that it will cause the xpath engine to use an optimized version
of [1].
But in reality, I simply shouldn't have to know this much to get it right.
If I use context and iterate on the same insert, I should get a binding
exception that informs me that one of "parent" or a "nodeset binding" is
required. Or if I want to use nesting for clarity, I should be able to
type this:
<xforms:action ev:event="custom-reverse">
<xforms:action iterate="some/list/*">
<xforms:insert parent=".." origin="."/>
</xforms:action>
<xforms:delete nodeset="some/list/*[position()*2 > last()]"/>
</xforms:action>
Finally, note that we added context to delete in XForms 1.1 so that insert
and delete could be written in a consistent manner. On the other hand,
the parent behavior really is a special case of insert, and there really
is no good analog in delete, so it could go either way -- add "parent" or
don't add "parent" as a special attribute of delete. But if we do add it
to delete, then it should probably be added to repeat as well so that
insert, delete and repeat nodeset expressions can be written in the same
way.
Thanks,
John M. Boyer, Ph.D.
Distinguished Engineer, IBM Forms and Smarter Web Applications
IBM Canada Software Lab, Victoria
E-Mail: boyerj@ca.ibm.com
Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer
Blog RSS feed:
http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw
Received on Monday, 31 October 2011 14:00:10 UTC