java - How to bind input externally to xquery using saxon? -
i have invoke external java methods in xquery using saxon he. able invoke methods below code. problem want bind input externally.
final configuration config = new configuration(); config.registerextensionfunction(new shiftleft()); final staticquerycontext sqc = new staticquerycontext(config); final xqueryexpression exp = sqc.compilequery(new filereader( "input/names.xq")); final dynamicquerycontext dynamiccontext = new dynamicquerycontext(config); string xml = "<student_list><student><name>george washington</name><major>politics</major><phone>312-123-4567</phone><email>gw@example.edu</email></student><student><name>janet jones</name><major>undeclared</major><phone>311-122-2233</phone><email>janetj@example.edu</email></student><student><name>joe taylor</name><major>engineering</major><phone>211-111-2333</phone><email>joe@example.edu</email></student></student_list>"; documentbuilderfactory newinstance = documentbuilderfactory.newinstance(); newinstance.setnamespaceaware(true); document parse = newinstance.newdocumentbuilder().parse(new inputsource(new stringreader(xml))); documentwrapper sequence = new documentwrapper(parse, "", config); structuredqname qname = new structuredqname("", "", "student_list"); dynamiccontext.setparameter(qname, sequence); properties props = new properties(); final sequenceiterator iter = exp.iterator(dynamiccontext); props.setproperty(outputkeys.omit_xml_declaration, "yes"); props.setproperty(outputkeys.indent, "yes"); stringwriter writer = new stringwriter(); queryresult.serializesequence(iter, config, writer, props); system.out.println("result " + writer);
names.xq
declare namespace eg="http://example.com/saxon-extension"; declare namespace xs = "http://www.w3.org/2001/xmlschema"; declare variable $student_list element(*) external; <students> <value> { let $n := eg:shift-left(2, 2) return $n }</value> <student_names> { $student_list//student_list/student/name } </student_names> </students>
but getting below error
error @ procedure student_list on line 3 of students.xml: xpty0004: required item type of value of variable $student_list element(); supplied value has item type document-node(element(q{}student_list)) net.sf.saxon.trans.xpathexception: required item type of value of variable $student_list element(); supplied value has item type document- node(element(q{}student_list)) @ net.sf.saxon.expr.itemtypecheckingfunction.testconformance(itemtypecheckingfunction.java:69) @ net.sf.saxon.expr.itemtypecheckingfunction.mapitem(itemtypecheckingfunction.java:50) @ net.sf.saxon.expr.itemmappingiterator.next(itemmappingiterator.java:95) @ net.sf.saxon.expr.cardinalitycheckingiterator.<init>(cardinalitycheckingiterator.java:52) @ net.sf.saxon.type.typehierarchy.applyfunctionconversionrules(typehierarchy.java:230) @ net.sf.saxon.expr.instruct.globalparameterset.convertparametervalue(globalparameterset.java:105) @ net.sf.saxon.expr.instruct.bindery.useglobalparameter(bindery.java:136) @ net.sf.saxon.expr.instruct.globalparam.evaluatevariable(globalparam.java:62) @ net.sf.saxon.expr.globalvariablereference.evaluatevariable(globalvariablereference.java:105) @ net.sf.saxon.expr.variablereference.evaluateitem(variablereference.java:460) @ net.sf.saxon.expr.atomizer.evaluateitem(atomizer.java:313) @ net.sf.saxon.expr.atomizer.evaluateitem(atomizer.java:35) @ net.sf.saxon.expr.atomicsequenceconverter.evaluateitem(atomicsequenceconverter.java:275) @ net.sf.saxon.expr.atomicsequenceconverter.evaluateitem(atomicsequenceconverter.java:30) @ net.sf.saxon.functions.doc.doc(doc.java:235) @ net.sf.saxon.functions.doc.evaluateitem(doc.java:190) @ net.sf.saxon.functions.doc.evaluateitem(doc.java:28) @ net.sf.saxon.expr.simplestepexpression.iterate(simplestepexpression.java:85) @ net.sf.saxon.expr.slashexpression.iterate(slashexpression.java:842) @ net.sf.saxon.expr.sort.documentsorter.iterate(documentsorter.java:168) @ net.sf.saxon.expr.slashexpression.iterate(slashexpression.java:842) @ net.sf.saxon.expr.sort.documentsorter.iterate(documentsorter.java:168) @ net.sf.saxon.expr.expression.process(expression.java:552) @ net.sf.saxon.expr.instruct.elementcreator.processleavingtail(elementcreator.java:450) @ net.sf.saxon.expr.instruct.elementcreator.processleavingtail(elementcreator.java:389) @ net.sf.saxon.expr.instruct.block.processleavingtail(block.java:669) @ net.sf.saxon.expr.instruct.instruction.process(instruction.java:144) @ net.sf.saxon.expr.instruct.elementcreator.constructelement(elementcreator.java:539) @ net.sf.saxon.expr.instruct.elementcreator.evaluateitem(elementcreator.java:476) @ net.sf.saxon.expr.instruct.instruction.iterate(instruction.java:363) @ net.sf.saxon.query.xqueryexpression.iterator(xqueryexpression.java:332) @ com.example.saxon.externalmethodcaller.main(externalmethodcaller.java:77)
thanks in advance..
unless have reason not to, advice use snappi (the saxon 9 api, or s9api):
processor saxon = new processor(false); saxon.registerextensionfunction(new myextension()); xquerycompiler compiler = saxon.newxquerycompiler(); xqueryexecutable exec = compiler.compile(new file("input/names.xq")); xqueryevaluator query = exec.load(); documentbuilder builder = saxon.newdocumentbuilder(); string students = "<xml>...</xml>"; source src = new streamsource(new stringreader(students)); xdmnode doc = builder.build(src); query.setexternalvariable(new qname("student_list"), doc); xdmvalue result = query.evaluate();
with myextension
looking following:
public class myextension implements extensionfunction { @override public qname getname() { return new qname("http://example.org/my-project", "my-fun"); } @override public sequencetype getresulttype() { return sequencetype.makesequencetype( itemtype.integer, occurrenceindicator.one); } @override public sequencetype[] getargumenttypes() { return new sequencetype[] { sequencetype.makesequencetype( itemtype.integer, occurrenceindicator.one), sequencetype.makesequencetype( itemtype.integer, occurrenceindicator.one) }; } @override public xdmvalue call(xdmvalue[] args) throws saxonapiexception { long first = ((xdmatomicvalue)args[0].itemat(0)).getlongvalue(); long second = ((xdmatomicvalue)args[0].itemat(0)).getlongvalue(); long result = ...; return new xdmatomicvalue(result); } }
see documentation @ http://www.saxonica.com/documentation9.5/extensibility/integratedfunctions/ext-simple-j.html details.
expath has project called tools-saxon
, containing several tools using saxon in java. including extension functions. introduces concept of function library, convenient if have several extension functions. introduces function definition builder, allowing 1 build function definition less boiler plate code possible (and providing convenient shortcuts type sequences). in above code, replace function registering (the first 2 lines) by:
processor saxon = new processor(false); library lib = new mylibrary(); lib.register(saxon.getunderlyingconfiguration());
and replace extension class 2 following classes (a library , function, resp.):
public class mylibrary extends library { public mylibrary() { super("http://example.org/my-project", "my"); } @override protected function[] functions() { return new function[] { new myfunction(this) }; } } public class myfunction extends function { public myfunction(library lib) { super(lib); } @override protected definition makedefinition() { return library() .function(this, "my-fun") .returns(types.single_integer) .param(types.single_integer, "first") .param(types.single_integer, "second") .make(); } @override public sequence call(xpathcontext ctxt, sequence[] args) throws xpathexception { parameters params = checkparams(args); long first = params.aslong(0, true); long second = params.aslong(1, true); long result = 0; return return.value(result); } }
see informatio on project home on github, @ https://github.com/expath/tools-saxon.
note: not tested.
Comments
Post a Comment