Search code examples
xquerymarklogic

Passing XQuery xml element as external variable to Marklogic via XCC


We have a fairly simple XQuery and Groovy code as follows. Xquery code :

declare variable $criteria as element(criteria) external ;

<scopedInterventions>{
$criteria/equals/field
}</scopedInterventions>

Here is the test code that is trying to invoke it

def uri = new URI("xcc://admin:admin@localhost:8001")

def contentSource = ContentSourceFactory.newContentSource(uri)

def request = session.newModuleInvoke("ourQuery.xqy")
def criteria =
"""<criteria>
<equals>
<field>status</field>
<value>draft</value>
</equals>
</criteria>
"""

request.setNewVariable("criteria",ValueType.ELEMENT, criteria);

session.submitRequest(request).asString()
}

We are getting this error when executing:

Caused by: com.marklogic.xcc.exceptions.XQueryException: XDMP-LEXVAL: xs:QName("element()") -- Invalid lexical value "element()" [Session: user=admin, cb={default} [ContentSource: user=admin, cb={none} [provider: address=localhost/127.0.0.1:9001, pool=1/64]]] [Client: XCC/5.0-3, Server: XDBC/5.0-3] expr: xs:QName("element()") at com.marklogic.xcc.impl.handlers.ServerExceptionHandler.handleResponse(ServerExceptionHandler.java:34) at com.marklogic.xcc.impl.handlers.EvalRequestController.serverDialog(EvalRequestController.java:83) at com.marklogic.xcc.impl.handlers.AbstractRequestController.runRequest(AbstractRequestController.java:84) at com.marklogic.xcc.impl.SessionImpl.submitRequestInternal(SessionImpl.java:373) at com.marklogic.xcc.impl.SessionImpl.submitRequest(SessionImpl.java:356) at com.zynx.galen.dataaccess.MarkLogicUtilities.executeQueryWithMultipleXMLParameters(MarkLogicUtilities.groovy:52) at com.zynx.galen.repositories.ScopedInterventionService.getScopedInterventionsByCriteria(ScopedInterventionService.groovy:20) ... 1 more

Any help would be greately appreciated.


Solution

  • http://docs.marklogic.com/javadoc/xcc/overview-summary.html has the answer, I think:

    Passing Variables With Queries

    Variables may be bound to Request objects. When an execution request is issued to the server with Session.submitRequest(Request) all the variables currently bound to the Request object are sent along and defined as external variables in the execution context in the server.

    XCC lets you create XdmNodes and XdmSequences, as well as XdmAtomic values. However, in the initial XCC release values of this type may not be bound as external variables because MarkLogic Server cannot yet accept them. This capability is anticipated for a future release.

    Since XdmNode is not supported, I suppose its subclass XdmElement is not supported either. So these classes are only useful for responses, not requests. The error message could stand to be improved.

    You could pass the XML string using setNewStringVariable, then call xdmp:unquote in your XQuery module. Note that xdmp:unquote returns a document-node, so the /* XPath step yields its root element.

    declare variable $xml-string as xs:string external ;
    declare variable $criteria as element(criteria) := xdmp:unquote($xml-string)/* ;
    ....