External functions in XQuery
I recently implemented a (IMHO) much handier way to provide external functions to XQueries in X-Hive/DB.
External functions can be declared in XQuery like this:
declare function myfunc($a, $b, $c) external;
In X-Hive, you can now create a statement on an arbitrary XML node, register functions, and execute the query (this is from memory and will probably not compile like that):
XhiveNodeIf node = ...;
XhiveXQueryQuery statement = node.createXQuery(
"declare function extract-post($author, $title, $content, $time) external;" +
"declare namespace dc = 'http://purl.org/dc/elements/1.1/';" +
"declare namespace content= 'http://purl.org/rss/1.0/modules/content/';" +
"for $item in /rss/channel/item" +
"return extract-post($item/dc:creator, $item/title, $item/content:encoded, $item/pubDate)")
ArrayList posts = new ArrayList();
statement.setExternalFunction(null, "extract-post", new XhiveExtensionFunctionIf() {
Object[] call(Iterator< ? extends XhiveXQueryValueIf>[] params) {
String author = params[0].next().toString();
...
posts.add(new RSSPost(author, title, content, date));
return null;
}
});
statement.execute();
While in general you have to be very careful with functions having side effects, this is a pretty handy way to extract Java objects from a given XML source. As long as you do not make any assumptions about the order, in which the function calls happen, it should also not break.
There are quite a lot of other projects about converting your XML into Java objects (e.g. Apache XMLBeans or DAX). Using XQuery has the advantage of giving you a real XML query language at hand for value extraction, and in combination with an XML database you can also handle really large documents very efficiently.