You can import XQuery into other XQuery and/or Server-Side JavaScript modules. Similarly, you can import XSLT stylesheets into other stylesheets, you can import XQuery modules into XSLT stylesheets, and you can import XSLT stylesheets into XQuery modules.
This chapter describes the two types of XQuery modules and specifies the rules for importing modules and resolving URI references. To import XQuery into Server-Side JavaScript modules, see Using XQuery Functions and Variables in JavaScript in the JavaScript Reference Guide.
This chapter covers the following topics:
For details on importing XQuery library modules into XSLT stylesheets and vice-versa, see Notes on Importing Stylesheets With <xsl:import> and Importing a Stylesheet Into an XQuery Module in the XQuery and XSLT Reference Guide.
There are two types of XQuery modules (as defined in the XQuery specification, http://www.w3.org/TR/xquer//#id-query-prolog):
For more details about the XQuery language, see the XQuery and XSLT Reference Guide.
A main module can be executed as an XQuery program, and must include a query body consisting of an XQuery expression (which in turn can contain other XQuery expressions, and so on). The following is a simple example of a main module:
"hello world"
Main modules can have prologs, but the prolog is optional. As part of a prolog, a main module can have function definitions. Function definitions in a main module, however, are only available to that module; they cannot be imported to another module.
A library module has a namespace and is used to define functions. Library modules cannot be evaluated directly; they are imported, either from other library modules or from main modules with an import
statement. The following is a simple example of a library module:
xquery version "1.0-ml"; module namespace hello = "helloworld"; declare function helloworld() { "hello world" };
If you insert the module into the modules database of your App Server or save it on the filesystem under the modules root directory of your App Server, then you can import the module and call the helloworld function.
For example, suppose you save the above module to the filesystem with the pathname /my/app/helloworld.xqy
. If you configure an App Server to use Modules as the modules database and / as the modules root, then you can store the module in the modules database as follows:
xquery version "1.0-ml"; xdmp:eval('xdmp:document-load("/space/rest/helloworld.xqy")', (), <options xmlns='xdmp:eval'> <database>{xdmp:database('Modules')}</database> </options>)
The inserted module has the URI /my/app/helloworld.xqy
. Now, you can import the module in a main module or library module and call the helloworld function as follows:
xquery version "1.0-ml"; import module namespace hw="helloworld" at "/my/app/helloworld.xqy"; hw:helloworld()
The same import statement works if you configure an App server to use the filesystem as the modules database and / as the modules root. In this case, the query imports the module from the filesystem instead of from the modules database.
In order to call a function that resides in an XQuery library module, you need to import the module with its namespace. MarkLogic Server resolves the library paths similar to the way other HTTP and application servers resolve their paths. Similarly, if you use xdmp:invoke or xdmp:spawn to run a module, you specify access to the module with a path. These rules also apply to the path to an XSLT stylesheet when using xdmp:xslt-invoke, as well as to stylesheet imports in the <xsl:import>
or <xsl:include>
instructions.
The XQuery module that is imported/invoked/spawned can reside in any of the following places:
When resolving import
/invoke
/spawn
paths, MarkLogic first resolves the root of the path, and then looks for the module under the Modules directory first and the App Server root second, using the first module it finds that matches the path.
The paths in import
/invoke
/spawn
expressions are resolved as follows:
import
/invoke
/spawn
path starts with a leading slash, first look under the Modules directory (on Windows, typically c:\Program Files\MarkLogic\Modules
). For example: import module "foo" at "/foo.xqy";
In this case, it would look for the module file with a namespace foo
in c:\Program Files\MarkLogic\Modules\foo.xqy
.
/home/mydocs/
, then the following import:import module "foo" at "/foo.xqy";
will look for a module with namespace foo
in /home/mydocs/foo.xqy
.
Note that you start at the App Server root, both for filesystem roots and Modules database roots. For example, in an App Server configured with a modules database and a root of http://foo/
:
import module "foo" at "/foo.xqy";
will look for a module with namespace foo
in the modules database with a URI http://foo/foo.xqy
(resolved by appending the App Server root to foo.xqy
).
/home/mydocs/bar.xqy
has the following import: import module "foo" at "foo.xqy";
it will look for the module with namespace foo
at /home/mydocs/foo.xqy
.
Note that you start at the calling module location, both for App Servers configured to use the filesystem and for App Servers configured to use modules databases. For example, a module with a URI of http://foo/bar.xqy
that resides in the modules database and has the following import
statement:
import module "foo" at "foo.xqy";
will look for the module with the URI http://foo/foo.xqy
in the modules database.
import module "foo" at "http://foo/foo.xqy";
will throw an invalid path exception. Similarly:
import module "foo" at "c:/foo/foo.xqy";
When XQuery modules (or XSLT files) are stored in the root for an App Server configured in MarkLogic Server, when they are first accessed, each module is parsed and then cached in memory so that subsequent access to the module is faster. If a module is updated, the cache is invalidated and each module for that App Server requires parsing again the next time it is evaluated. The module caching is automatic and therefore is transparent to developers. When considering the naming of modules, however, note the following:
application/vnd.marklogic-xdmp
or application/xslt+xml
mimetypes. By default, this includes the extensions xqy
, xq
, and xslt
. You can add other extensions to these mimetypes using the mimetypes configuration in the Admin Interface.application/vnd.marklogic-xdmp
or application/xslt+xml
will not invalidate the module cache, and therefore you must reload the cache on each host (for example, by restarting the server or modifying a module with the proper extension) to see changes in a module that does not have the correct extension.Consider the following scenario:
c:/mydir
.c:/mydir/lib.xqy
, there is a library module with the function to import. The contents of the library module are as follows: xquery version "1.0-ml"; module namespace hw="http://marklogic.com/me/my-module"; declare function hello() { "hello" };
c:/mydir/main.xqy
, there is an XQuery main module that imports a function from the above library module. This code is as follows: xquery version "1.0-ml"; declare namespace my="http://marklogic.com/me/my-module"; import module "http://marklogic.com/me/my-module" at "lib.xqy"; my:hello()
The library module lib.xqy
is imported relative to the App Server root (in this case, relative to c:/mydir
).