There are some troublesome aspects to the behaviour of the insert element.
http://www.w3.org/TR/2002/CR-xforms-20021112/slice9.html#action-insert
In the following simple example, we must copy the last <y /> child of <x />
in the initial instance, and insert it into the live instance under <x />.
<xf:insert nodeset="x/y" />
There are two options for cloning, the required node can be cloned either on
request, or in the initialization phase and stored. Either method is fine.
For the insert location, however, this must be stored at initialization
time. If all <y /> nodes are deleted at runtime, the XPath statement "x/y"
will no longer bind to a homogenous collection, so the insert location
cannot be resolved. You may suggest that the parent node could be derived
from the XPath statement by removing "/y" to return "x", but consider the
following statement:
<xf:insert nodeset="//y" />
If the author knows that there somewhere in the document, there is a node
that contains all of the <y /> elements, then this will return a homogenous
collection. If all of those <y /> elements are deleted, there is no longer
any way of finding that parent.
The problem with resolving either insertion point or template node at
initialization time can be illustrated below:
<xf:insert nodeset="x[position()=/*/@n]/y" />
Here, the author wishes to resolve both nodes, conditional on the value of
another node. Is that other node live, or from the initial instanceData?
In order for it to make sense in XPath, it must be from the same document as
the required resulting node. That means, that for determination of
node-to-clone, it must be from the initial, but for determination of
insertion point, it has to be live.
This is contrary to the needs outlined above, where insertion point must be
resolved during initialization. It is also wrong, since the collection
pointed to in the initial instance data is not really the "corresponding
node-set" to the live one. In order for the real corresponding node-set to
be returned, some nodes referred to in square brackets in the XPath
statement must be live, but others may have to be resolved in the initial
instance data.
One way around this is simply to resolve both nodes in the live
instanceData. If an attempt is made to insert into an empty nodelist, the
processor should give an error. This would keep the behaviour approximately
the same as the spec, but remove the interpretation difficulty. This is the
current behaviour of Formsplayer. However, this approach has limitations.
Often, an author can have little or no control over the format of the XML in
an instance, it may come from a Web Services query or a database belonging
to another organisation. In this situation, it would be impossible for
XForms to insert data into an empty list without resorting to programmatic
access to the DOM via a script written by the forms author.
We propose that a better solution would be to resolve the insertion point
with one XPath statement, pointing to the node into which the new node will
be inserted, and node-to-insert with another statement, specifying the node
to copy. This would also facilitate cross-instance copying of data,
allowing XForms to populate lists with no initial members.
The format for insert could be:
<xf:insert
newChild="XPATH"
parent="XPATH"
at="XPATH"
position="before|after"
/>
Paul Butcher
FormsPlayer Lead Programmer
x-port.net Ltd.
4 Pear Tree Court
London
EC1R 0DS
Try our XForms plug-in for IE
at http://www.FormsPlayer.com/