Open main menu



You want to allow the user to save form data into a named file in an eXist collection that will not conflict with existing files.


When the user selects a Save button we will use switch/case to open up a save dialogue. In this dialogue we will list all of the current files in a collection and allow the user to create a new file with a name that does not conflict with any existing file names. If the user selects a file from the list, we will replace the current file name with that file name.

Using the get-child-resources FunctionEdit

eXist provides a function that lists the files in a collection. You can get a sorted list of all the files in a collection with the following XQuery

xquery version "1.0";
declare namespace xdb="";
declare option exist:serialize "method=xml media-type=text/xml indent=yes";

let $collection := request:get-parameter('collection', '/db/test')

         for $child in xdb:get-child-resources($collection)
         order by lower-case($child)

When executed, this XQuery will return the files in a collection. For example here is the URL of an XQuery execution with the collection parameter passed as an argument:



We can then use this XML listing to display a list of existing files and allow the user to select a name that is not on this list.

Sample ProgramEdit

<html xmlns="" xmlns:ev="" xmlns:xsd="" xmlns:xf="">
        <title>Save File Dialog</title>
        <link type="text/css" rel="stylesheet" href="save-panel.css" />

            <!-- This is the data that we want to save to a file on the server. -->
            <xf:instance id="my-data" xmlns="">
                    <element1>Element 1</element1>
                    <element2>Element 2</element2>
                    <element3>Element 3</element3>
                    <!-- This is the file name that we are going to save the data into. -->
            <!-- Placeholder for the list of files in the target collection. -->
            <xf:instance xmlns="" id="list-files-results">
            <!-- This does the save. The server-side script must look for the filename element to do the save
                to the correct file.  -->
            <xf:submission id="save" method="post" action="save.xq" ref="my-data" replace="all" />
            <!-- Gets the list of current files in the server-side collection and puts them in the model. -->
            <xf:submission id="list-files" method="post" action="list-files.xq" replace="instance" instance="list-files-results" />
        <h1>Example of Save File Panel</h1>
        <xf:input ref="element1">
            <xf:label>Element 1:</xf:label>
        <xf:input ref="element2">
            <xf:label>Element 2:</xf:label>
        <xf:input ref="element3">
            <xf:label>Element 3:</xf:label>
            <xf:case id="default">
                <xf:submit submission="save">
                    <xf:label>Save As...</xf:label>
                    <xf:toggle case="save-dialog" ev:event="DOMActivate" />
            <xf:case id="save-dialog">
                <xf:action ev:event="xforms-select">
                    <xf:send submission="list-files" />
                <!-- This turns all the files into buttons that can be selected to select a specific file. -->
                <xf:repeat nodeset="instance('list-files-results')/file" class="list-files" id="list-files-repeat">
                    <xf:trigger appearance="minimal">
                            <xf:output ref="." />
                        <xf:action ev:event="DOMActivate">
                            <!-- Set the filename that we will save to to the value under the selected item. -->
                                value="instance('list-files-results')/file[index('list-files-repeat')]" />
                <xf:input ref="instance('my-data')/filename">
                    <xf:label>File Name:</xf:label>
                <xf:submit submission="list-files">
                <xf:submit submission="save">

CSS FileEdit

@namespace xf url("");

body {font-family: Helvetica, sans-serif;}

.list-files {
   font-size: .8em;
   color: blue;
   background-color: white;
   border: 1px solid black;
   padding: 5px;