marklogic rest call with xpath manipulation [junk after document element]

188 Views Asked by At

I've been working through a tutorial to build a rest service with marklogic. I've built a simple example through using roxy deploy tool and calling ml ext . My problem is trying to grab a specific element out of a document via rest call. Here is what i have so far:

    declare
%roxy:params("dataType=xs:string","pNumber=xs:number", "sNumber=xs:string", "searchTerm=xs:string")
function jad:get(
  $context as map:map,
  $params  as map:map
) as document-node()*
{
  map:put($context, "output-types", "application/xml"),
  map:put($context, "accept-types", "multipart/mixed"),
  map:put($context, "output-status", (200, "OK")),
  let $doc := doc('testNew.xml')
  let $docs := $doc//stuff/pData/sData/headerData/bData/sitData[contains(., 'word')]
  let $c := json:config("custom"),

   $_ := map:put($c,"whitespace", "ignore"),
   $_ := map:put( $c , "camel-case" , fn:true() )
   let $results := search:search("word",
   <options xmlns="http://marklogic.com/appservices/search">
     <transform-results apply="raw"/>
   </options>)
return document{$doc//stuff/pData/sData/headerData/bData/sitData[contains(., 'word')]}

this has gone through many iterations but ultimately the problem is I can't seem to simply return a document along an xpath within rest. When I call upon this url I get an error like this:

enter image description here

After reading through many stackoverflow links this seems to stem from the Xpath only returning a snippet. The problem is I don't know how to return the full results. I had read somewhere that I could set a property somewhere in my "rest-api" folder to be but this hasn't stopped this problem. So what I would ultimately like is the possibility to search a specific document's internal structure for keywords.

EDIT: would I be better off using RXQ for this purpose?

1

There are 1 best solutions below

4
On

Based on your comments:

If I want to search a specific document in the database I'm not sure how to accomplish that without using xpath

If you know the URI of the document you want to return, you can get that one with fn:doc($uri).

if I have multiple xml snippets from the document, how can I just send them along as a single document

This should do it:

let $results := search:search("word",
  <options xmlns="http://marklogic.com/appservices/search">
    <transform-results apply="raw"/>
  </options>)
return document { $results }

search:search returns a single XML element; you need to return a document-node, so I've wrapped the search results in document { }.

If you wanted to return multiple elements, you'll need to enclose them in a single parent, as an XML document may only have one root:

return document{
  <root>{
    $doc//stuff/pData/sData/headerData/bData/sitData[contains(., 'word')]
  }</root>
}

Also, looking at your HTTP call:

http://localhost:8040/v1/resources/decosta?dataType=thing&policyNumber=1234&searchTerm=thisthingrighthere

Parameters for REST API extensions are required to have an "rs:" prefix on them, to distinguish from parameters for the REST API itself. So your URL should look like this:

http://localhost:8040/v1/resources/decosta?rs:dataType=thing&rs:policyNumber=1234&rs:searchTerm=thisthingrighthere

In your extension, you can then access the parameters like this:

let $data-type := map:get($params, "dataType")