Skip to content

Latest commit

 

History

History
173 lines (117 loc) · 6.28 KB

README.md

File metadata and controls

173 lines (117 loc) · 6.28 KB

saxon-marklogic-ext

Extension functions for Saxon allowing XQueries to be sent to MarkLogic Server.

The extensions may be registered:

  • in a Java program, by calling Saxon method registerExtensionFunction() and supplying the extension classes - for instance: configuration.registerExtensionFunction(new MarkLogicQuery());
  • through a Saxon Configuration file (Saxon documentation).

They are also gaulois-pipe services. The jar just has to be in the classpath for the functions to be used with gaulois-pipe.

The project is officially built around Saxon 9 (HE/PE/EE) from Saxonica and XPath / XSLT 3.0.

Starting with release 1.3.0, Saxon 9.9 is the officially supported version (last Saxon 9.8 compatible release: 1.4.0-98).

Starting with release 1.1.0, Saxon 9.8 is the officially supported version (last Saxon 9.7 compatible release: 1.0.7-97).

Usage

Send the XQuery as a string

Java class: fr.askjadev.xml.extfunctions.marklogic.MarkLogicQuery

<xsl:sequence xmlns:mkl-ext="fr:askjadev:xml:extfunctions" select="
  mkl-ext:marklogic-query(
    'for $i in 1 to 10 return {$i}',
    map{
      'server':'localhost',
      'port':8004,
      'user':'admin',
      'password':'admin'
    }
  )"
/>

Invoke an XQuery module already deployed on MarkLogic Server

Java class: fr.askjadev.xml.extfunctions.marklogic.MarkLogicQueryInvoke

<xsl:sequence xmlns:mkl-ext="fr:askjadev:xml:extfunctions" select="
  mkl-ext:marklogic-query-invoke(
    '/path/to/module.xqy',
    map{
      'server':'localhost',
      'port':8004,
      'user':'admin',
      'password':'admin'
    }
  )"
/>

Read an XQuery file from an URI and run it

Java class: fr.askjadev.xml.extfunctions.marklogic.MarkLogicQueryInvoke

<xsl:sequence xmlns:mkl-ext="fr:askjadev:xml:extfunctions" select="
  mkl-ext:marklogic-query-uri(
    'file:/path/to/file.xqy',
    map{
      'server':'localhost',
      'port':8004,
      'user':'admin',
      'password':'admin'
    }
  )"
/>

Additional information

The second parameter is an XPath 3.0 map containing the server and database configuration.

The options "server" (xs:string), "port" (xs:integer), "user" (xs:string) and "password" (xs:string) are mandatory.

You can supply 2 additional options:

  • "database" (xs:string) : alternative database name, if not using the one associated with the HTTP server.
  • "authentication" (xs:string) : authentication method. Authorized values: "digest", "basic" (default).

There is also a third parameter that can be supplied as a XPath 3.0 map containing the external variables values. The map must be of type map(xs:QName, item()?), where :

  • each key is a xs:QName matching an external variable declaration in the XQuery script ;
  • each value must be a singleton or empty sequence (because of restrictions in the MarkLogic Java API).

Most of the XDM atomic and node types are supported (including maps and arrays), though there might be some unsupported ones or restrictions of usage. For instance, an empty-sequence() is sent as a xs:anyAtomicType("") to MarkLogic and thus cannot be casted as a node in the XQuery. Also, attribute(), comment() and processing-instruction() will be sent to MarkLogic wrapped in a dummy document element. If you want to pass multiple atomic values, use an array. For multiple nodes, wrap them inside a dummy element().

Example :

<xsl:sequence xmlns:mkl-ext="fr:askjadev:xml:extfunctions" select="
  mkl-ext:marklogic-query-uri(
    'file:/path/to/file.xqy',
    $configMap,
    map{
       QName('http://namespace','pre:string'):'string value',
       QName('http://namespace','pre:integer'):1,
       QName('http://namespace','pre:comment'):$comment
    }
  )"
/>
declare namespace pre="http://namespace";
declare variable $pre:string as xs:string external;
declare variable $pre:integer as xs:string external;
declare variable $pre:comment as document-node() external;
let $pre:comment := $pre:comment/comment()
[...]

The query can return node(s) (except attributes) or atomic value(s), though there might be some unsupported ones or restrictions of usage.

Current version: 1.4.0 (Saxon 9.9) / 1.4.0-98 (Saxon 9.8)

Maven support:

<dependency>
  <groupId>fr.askjadev.xml.extfunctions</groupId>
  <artifactId>marklogic</artifactId>
  <version>1.4.0</version>
</dependency>

Build

To build the project from the sources, follow these steps:

$ git clone https://github.com/AxelCourt/saxon-marklogic-ext.git
$ cd saxon-marklogic-ext
$ mvn clean package -DskipTests=true

Please note that you need to deactivate the tests using the parameter -DskipTests=true to be able to build the project, unless you have correctly configured your MarkLogic Server environment.

Testing

The tests require a running MarkLogic Server instance. By default, they are run under the following MarkLogic Server configuration:

  • MarkLogic Server runs on localhost.
  • There is a Test database associated with a HTTP Server on port 8004.
  • Username/password are admin/admin.
  • User needs to be rest-admin in MarkLogic.
  • The HTTP Server authentication scheme is basic.

If you wish to change this behaviour, you can add additional parameters to the test command-line which values will be used instead of the default ones.

Parameter Default values Usage Description
testServer localhost -DtestServer=10.11.12.90 The server on which to run the tests.
testPort 8004 -DtestPort=8999 The port to use to talk to the HTTP Server.
testUser admin -DtestUser=myUser An authorised user.
testPassword admin -DtestPassword=myPassword The user password.

Thanks

Many thanks to Christophe Marchand for the base code, and Emmanuel Tourdot for the improvements!

Go there for a BaseX similar extension function: https://github.com/cmarchand/xpath-basex-ext.