XQuery Updates
Saxon 9.1 introduces support for XQuery Updates.
To run an updating query from the command line, use the option -update:on
on the command line.
From Java, compile the query in the normal way, and use the method XQueryExpression.runUpdate()
to
execute the query. At present it is not possible to run updates using the higher-level interfaces in XQJ or S9API,
or using the .NET API.
To enable updating internally, an extension of the NodeInfo
interface has been introduced, called
MutableNodeInfo
. Currently the only tree implementation that supports this interface is the linked tree
(formerly called the standard tree). In principle updating should work with any tree model that supports this
interface, though at present there are probably some dependencies on the specific implementation.
The linked tree has been improved so that it can now handle schema type annotations, and there have been improvements to the way in which line number information is maintained.
Saxon does not currently include any locking code to prevent concurrent threads attempting to update the same document. This is something that applications must organize for themselves.
At the Java API level, updated documents are not automatically written back to disk. Rather, the runUpdate()
method returns a set containing the root nodes of documents that have been updated. This may include documents that were read
using the doc() or collection() functions as well as documents supplied as the context node of the query or by binding
external variables. It may also include documents (or elements) that were created by the query itself - but only if they have
been updated after their initial construction. There is a helper method QueryResult.rewriteToDisk
allowing such
documents to be written back to disk if required, at the URI determined by their document-uri()
property,
but this must be explicitly invoked by the application. Clearly if the application does not have write access to the URI,
this operation will fail.
Alternatively, updated documents may be written back to disk using the put()
function. Note that because
put()
delivers no result, there is a danger that it will be "optimized out" of the query. Saxon implements
put()
using the runtime code for xsl:result-document
, and the implementation currently
imposes similar restrictions: in particular, it must not be called while evaluating a variable or function.
Applications should access the updated document via the root nodes returned by the runUpdate()
function.
Use of NodeInfo
objects that were obtained before running the update is in general unsafe; while it will probably
work in most cases, there are some cases (particularly with attributes) where the NodeInfo
object returned to the
application is a snapshot created on demand, and this snapshot will not be updated when the underlying tree is changed.
Updates are not currently atomic, as required by the specification. In particular, if the update fails revalidation against the schema, it is not rolled back.