Search code examples
dockerxquerystoreexist-db

upload file to eXist-db running on Docker container


I'm using eXist-db over docker container - installing Java over Ubuntu, installing the eXist installation headless jar, and also adding data Volume (Azure file) to store all the physical files and the db data files.

I need to upload automatically files to the eXist-db, after I generate a new file and save it to the volume drive (using C#).

According to the eXist documentation on uploading files there are several methods to upload files to eXist, but none of them work for me.

  1. Dashboard or eXide - not relevant since these are GUI applications.
  2. Java Admin Client - not working because have no GUI -> I'm getting this failure: 'No X11 DISPLAY variable was set, but this program performed an operation which requires it...'
  3. Over REST or WebDAV via web client (using browser or by code), I can run XQuery for queries, but for storing new files, how?

So, the solution I found is to write an XQuery file, using the xmldb:store function.

This query saved the posted file using the specified name and location (in the volume), and the stored file can then be retrieved via REST or WebDAV.

But I feel that there must be a simpler solution...

Can anyone help?

BTW, here is the xmldb:store XQuery:

xquery version "3.1";

declare function local:upload() {
    let $filename := request:get-uploaded-file-name("file")
    let $log-in := xmldb:login("/db", "Admin", "admin")
    let $file := "file:///usr/new_file_location.xml"
    let $record := doc($file)
    let $store := xmldb:store("/db/akn", "new_file_name.xml",  $record)
    return
        <results>
            <message>File {$file} has been stored.</message>
        </results>
};

local:upload()

Solution

  • When starting eXist as described in the eXist Docker documentation - with it listening on port 8080 - you can access all of eXist's standard endpoints:

    • http://localhost:8080/exist/webdav/db for WebDAV
    • http://localhost:8080/exist/rest/db for REST
    • http://localhost:8080/exist/xmlrpc/db for XML-RPC
    • http://localhost:8080/exist/apps for apps installed in /db/apps.

    Of course if you've configured Docker's eXist to listen on a different port, just switch the port.

    Thus, to upload files to a Dockerized eXist programmatically, the methods outlined in the documentation article you referenced, Uploading files, should all work: WebDAV, client.sh, Ant, or even curl. For WebDAV, if you haven't configured users and passwords, you'd just connect with the URL http://localhost:8080/exist/webdav/db, username "admin", and a blank password. For Ant, see the Ant tasks documentation. For curl, you would perform an HTTP PUT request to the REST interface:

    curl -s -f -H 'Content-Type: application/xml' \
         -T <filename> \
         --user <user>:<password> \
         "http://localhost:8080/exist/rest/db/apps/<collection>/<filename>"