Martin Probst's weblog

External functions in XQuery

Saturday, June 4, 2005, 12:20 — 0 comments Edit

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 = ‘';" +
    “declare namespace 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;

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.

No comments.