How to load functions from a .xq module ...

2009-11-19
2013-06-05
  • John Newman

    John Newman - 2009-11-19

    Hello,

    We've been using mxquery for updates over the past few months, so far so good.  I need some help importing a module file containing a set of functions, I think it almost working.

    my-module.xq:
    module namespace myapp = "http://myapp.test.com"

    define updating function myapp:deleteElement($elementXML as element(), $name as xs:QName)  {
      delete nodes $elementXML/$name
    }

    (actual content is different, that function may not actually work, just a simple example)

    Context ctx = new Context();
    ctx.addModuleLocation("myapp", "file:///c/myapp.xq"); // actual path is calculated

    String xqueryExpression = "import module namespace myapp = \"[http://myapp.test.com/](http://myapp.test.com/%5C)"; myapp:deleteElement(<root><el /></root>, el)";

    I can confirm that the module file is being loaded and parsed, if i get the path wrong or a syntax error in there I get an error. The URI's in the .xq file & java code have to match as well.

    However I don't think just calling addModuleLocation() actually makes the fuctions available to the context, because when I try to run the query I get:

    function myapp:deleteElement with arity 2 is not available.

    Looking in the debugger I see the moduleLocation setup, but the function gallery is empty.

    So am I going about this correctly?  Am I missing a statement that will make this work?

    thanks!

     
  • Peter M. Fischer

    Dear newmjw,

    there is likely a small, but crucial mistake in the way you use the addModuleLocation() function:
    The first parameter is not the prefix of the module you may want to import, but its namespace URI, in your case "http://myapp.test.com/".

    According to the specification of XQuery, the identifier of a module is always its namespace id, every import can then use a different prefix.

    Could you try if this fixes your problem?

    Regards,
    Peter Fischer

     
  • Florent Georges

    Florent Georges - 2009-11-20

      Hi,

      In addition to Peter response, note that your module source contains two typos: the module instruction and the function definition have to be followed by a semi-colon (;).

      Hope that helps,

     
  • John Newman

    John Newman - 2009-11-20

    ah .. a big thanks to the both of you!  it is working now due to both of those problems. 

    SO now I have the function calls going, but I am running into some different problems converting the queries from just plain old strings to updating functions, but that is a different issue altogether.  I need to digest the xquery grammar, at this point it is still a bit erratic to me.

    Peter, to get this to work in mxquery I had to use the same pattern as in the examples, StoreExample, runUpdateStoreReuse.  It seems like a lot of extra work but if I understand correctly xquery updates don't happen "right away" and the 2nd query is necessary to retrieve the value after the update.

    Am I on the right track here or is there an easier way of using updating functions? 

    Thanks again

     
  • Peter M. Fischer

    Dear newmjw,

    the model XQuery Update uses is very similar to that of a database - all updates become visible at the end of a query/transaction. To query the results in MXQuery, one can either work by using the file system as a store (as shown in the command line examples), or re-use the stores as you do.
    I would have to know your use case better to recommend the best strategy.

    From a more general perspective, the W3C is working in removing some of the restrictions in XQuery Update (single snapshot, restrictions on the combinations of expressions) within . Compared to update, the proposal is much less mature, much more political and much less supported. MXQuery does partially support Scripting (as does Zorba), but there are very likely more bugs

    Regards,
    Peter Fischer

      : http://www.w3.org/TR/xquery-sx-10/

     
  • John Newman

    John Newman - 2009-11-24

    Thanks again for the clarification Peter.

    However I don't think any of this is going to work out ultimately.  Most of our functions use dynamic xpaths.  For example:

    declare updating function xx:deleteNode($fullXML, $pathToRemove)  {
       let $nodeToRemove := $fullXML//$pathToRemove
      return delete nodes ($nodeToRemove)
    };

    xx:deleteNode(<root><el ID="4" /><el ID="5"><el2 ID="6" /></el></root>, //root/el/el2)

    As far as I understand, to do that, I need an evaluate function, which mxquery does not appear to have at this time. =(  Or I can build the query dynamically and not use a function.  This is what we've been doing up to this point and are trying get away from.

    Is an evaluate() function on the radar at all for a future release?  Any other ways to do this?  Can I evaluate the path before calling the function and pass an instance of org.w3c.Node as $nodeToRemove to it?

     
  • Peter M. Fischer

    Dear newmjw,

    as you correctly recognized, general dynamic paths cannot be expressed within the limits of normal XQuery. At the moment, I cannot really provide a good time frame in which MXQuery will support a function like eval(), as it has not been a high-priority item so far.

    To solve your problem, I could see the following more short-term approaches:

    - If you are not bound to Java, you could use Zorba (), as it provides an eval() function
    - If you are somewhat restricted on the paths you are willing to support, certain tests (names, predicate values) can be expressed with variables, functions and FLWOR expressions, so this might overcome some of your limitations
    - By managing stores and queries by hand (and some dynamic query generation), you can approximate eval() - but this seems not be what you want

    Hope that helps,
    Peter

      : http://www.zorba-xquery.com/

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks