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 = ‘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.


No comments.