I’m trying to load an XQuery module with a simple function into the Modules database using the Marklogic query console.
xquery version "1.0-ml";
xdmp:document-insert("/my/app/my-module.xqy",
<module xmlns="http://marklogic.com/xdmp/module">
xquery version "1.0-ml";
module namespace my = "http://my.app/module";
declare function my:hello-world($content as xs:string) {
fn:concat("Hello from my module! ",$content)
};
</module>
When I try and run the above I get the following error: [1.0-ml] XDMP-UNDVAR: (err:XPST0008) Undefined variable $content
I don’t know what I’m missing, $content is defined as a function parameter and the function seems to work outside of doing it as an install:
xquery version "1.0-ml";
declare namespace my = "http://my.app/module";
declare function my:hello-world($content as xs:string) {
fn:concat("Hello from my module! ",$content)
};
my:hello-world('test')
That works.
I can load a function that doesn't have a parameter without error:
xquery version "1.0-ml";
xdmp:document-insert("/my/app/my-module.xqy",
<module xmlns="http://marklogic.com/xdmp/module">
xquery version "1.0-ml";
module namespace my = "http://my.app/module";
declare function my:hello-world() {
fn:concat("Hello from my module!","Test")
};
</module>)
I’m guessing its something basic that I’m miss understanding. Can someone help please?
Thank you
EDIT: Based on Chris's suggestion and some additional googling I removed the module tag and surrounded the module with the text{} wrapper:
xdmp:document-insert("/my/app/my-test.xqy",
text{
'xquery version "1.0-ml";
module namespace my = "http://my.app/module";
declare function my:hello-world($content as xs:string) {
fn:concat("Hello from my module! ",$content)
};'
},
xdmp:default-permissions(),
"http://my.app/module"
)
And it ran fine and allowed me to call it via:
import module namespace my="http://my.app/module" at "/my/app/my-test.xqy";
my:hello-world("TEST")
The braces ({ ... }) are directives in XQuery to evaluate their contents. If you look at what your working attempt actually stored, you will probably see that the fn:concat() function was evaluated. Similarly, in your first attempt, the reference to $content is being evaluated, but the declaration, outside the braces, is not evaluated and so is unavailable.
You need to escape the braces by doubling them: {{ ... }}.
I am not sure what you are doing with the <module> element, however. It’s not a construct I’ve ever seen, and I get an error trying to use an XQuery module that is not plain text. I recommend defining the module content as a string and inserting that.