How to call XQuery function from Java?

Wednesday, 23 February 2022 · 2 messages
PJ
Paul L. Merchant Jr.23 Feb 2022 17:57 #
Is it possible for a Java function called from XQuery in BaseX to call back to an XQuery function that's passed to it in BaseX? I haven't been able to find any documentation or examples of this. I got the following example to work, but it doesn't feel right. Is there a better way that might take advantage of the automatic type conversions BaseX performs and doesn't require calling something named "...Internal"? Thanks! ------------------- xquery ------------------- import module namspace java = 'java:my.Module;
declare function local:hello($p as xs:string) as xs:string {
	concat("Hello ", $p)
};

java:invoke(local:hello#1)
------------------- Java ------------------- package my; import java.io.UnsupportedEncodingException;
import org.basex.query.QueryException;
import org.basex.query.QueryModule;
import org.basex.query.value.type.AtomType;
import org.basex.query.value.item.FuncItem;
import org.basex.query.value.item.Str;
import org.basex.query.value.Value;
import org.basex.util.InputInfo;

public class Module extends QueryModule {
  public String invoke(final FuncItem func) throws UnsupportedEncodingException, QueryException {
    InputInfo ii = new InputInfo("my.Module.invoke", 0, 0);
    String s = "Java";
    Str p1 = new Str(s.getBytes("UTF-8"), AtomType.STRING);
    Value[] args = new Value[] {p1};
    String r = (String) func.invokeInternal(queryContext, ii, args).toJava();

    return r;
  }
}
CG
Christian Grün23 Feb 2022 18:39 #
Hi Paul.
Quoted text · Paul L. Merchant Jr. · 1 line
> Is it possible for a Java function called from XQuery in BaseX to call back to an XQuery function that's passed to it in BaseX?
Your solution looks fine; it can be further simplified: package my;
import org.basex.query.*;
import org.basex.query.value.*;
import org.basex.query.value.item.*;

public class Module extends QueryModule {
  public Value invoke(FuncItem func) throws Exception {
    return func.invoke(queryContext, null, Str.get("Java"));
  }
}
Best, Christian I haven't been able to find any documentation or examples of this. I got the following example to work, but it doesn't feel right. Is there a better way that might take advantage of the automatic type conversions BaseX performs and doesn't require calling something named "...Internal"?
Quoted text · Paul L. Merchant Jr. · 45 lines
> > Thanks! > > > ------------------- > xquery > ------------------- > > import module namspace java = 'java:my.Module; > > declare function local:hello($p as xs:string) as xs:string { > concat("Hello ", $p) > }; > > java:invoke(local:hello#1) > > > ------------------- > Java > ------------------- > > > package my; > > import java.io.UnsupportedEncodingException; > > import org.basex.query.QueryException; > import org.basex.query.QueryModule; > import org.basex.query.value.type.AtomType; > import org.basex.query.value.item.FuncItem; > import org.basex.query.value.item.Str; > import org.basex.query.value.Value; > import org.basex.util.InputInfo; > > public class Module extends QueryModule { > public String invoke(final FuncItem func) throws UnsupportedEncodingException, QueryException { > InputInfo ii = new InputInfo("my.Module.invoke", 0, 0); > String s = "Java"; > Str p1 = new Str(s.getBytes("UTF-8"), AtomType.STRING); > Value[] args = new Value[] {p1}; > String r = (String) func.invokeInternal(queryContext, ii, args).toJava(); > > return r; > } > }

⚡Generated with XQuery