0
votes

I am new to saxon using it to process existing xqueries. I can execute simple xquery with primitive types(simple types) from java class as below:

Xquery:
declare function xf:addNumberss($int1 as xs:int,
$int2 as xs:int)
as xs:int {
    <value>{data($int1)+data($int2)}</value>

};

Java:
final Sequence[] arglist = new Sequence[2];
    arglist[0] = new Int64Value(10);
    arglist[1] = new Int64Value(10);
        arglist[0] = new Int64Value(request.getNo1());
        arglist[1] = new Int64Value(request.getNo2());
        Sequence result = null;
        try {
            result = fn1.call(arglist, controller);

where I am getting the expected response. But I am stuck how to pass a complex element as input to Xquery

Ex: Xquery

declare function xf:addNumbersByElements($addNumbers1 as element(ns0:addNumbers))
as element(ns0:addNumbersResponse) {
    <ns0:addNumbersResponse>
        <ns0:response>
            <ns0:result>{ data($addNumbers1/ns0:request/ns0:no1) + data($addNumbers1/ns0:request/ns0:no2) }</ns0:result>
        </ns0:response>
    </ns0:addNumbersResponse>

Java:
final Sequence[] arglist = new Sequence[1];
    arglist[0] = (Sequence)addNumType;

Unable to convert AdNumType complex type to sequence Exception:java.lang.ClassCastException: com.xq.AddNumbersType incompatible with net.sf.saxon.om.Sequence

Could anyone please help how to convert complex type to xquery input in Saxon. Also please suggest any tutorial links available apart from API reference guide.

Thanks

1
Thanks for the response. I will check the above links - Rama krishna

1 Answers

0
votes

I would recommend using the s9api interface (classes like XdmValue, XdmAtomicValue, XdmNode) rather than the lower-level interfaces (classes like NodeInfo, Int64Value, Sequence), because the lower-level interfaces expose too much internal complexity and are not so stable between releases.

At the s9api level, you can compile your query using XQueryCompiler.compile() to return an XQueryExecutable; call load() on this to get an XQueryEvaluator, and then call callFunction() on this to call a specific XQuery function. The callFunction() method takes arguments and returns results in the form of XdmValue instances. If the query returns a node, it will be in the form of an XdmNode instance, and you can run a further query on this XdmNode by setting it as the context item for another query using XQueryEvaluator.setContextItem().

If you do want to use the lower-level interface, Sequence is an interface and you will have to choose a specific implementation. For a sequence that is a single node, the sub-interface NodeInfo is suitable; but you need to be aware that when a function returns a single node, it won't necessarily be returned as an instance of NodeInfo, it might for example by a LazySequence whose head() method needs to be called to obtain the NodeInfo. You really don't want to get involved with such complexities if you can avoid it; so use s9api.