RE: Loading & saving documents

Hi Flinton,

There are two aspects to your question. The first is the ability to load and
save from the local drive, and the second is the ability to load and save
from a location determined by the user. I'll look at these two, as well as
explain how to bootstrap the whole thing when there is no initial document
(i.e., on first run of your form).

(I've also just posted the following to the XForms Wiki at SaveLocalFiles.)

  * Accessing Local Files
  * Initialising the Local File
  * User-Specified URLs
    * Choosing a URI


ACCESSING LOCAL FILES
XForms processors are not required to support the "file:" protocol, but as
far as I know, most of the client-side XForms processors do. By this I mean
formsPlayer, Novell, X-Smiles and Mozilla (apologies if I have missed
anyone!), although you would have to check with each what the security
restrictions are. The methods applicable to "file:" will usually be "get"
and "put".

Speaking only for formsPlayer, our approach is to prompt the user on *any*
load or save of a local file, and I think some other processors do the same.

In addition to the "file:" protocol, formsPlayer implements an experimental
protocol called "cookie:", which allows you to load and save XML documents
locally without the user being prompted. This is deemed safe because the
location for the file is forced to be in in a sub-directory in the user's
local store (i.e., home directory) so there is no way to get out of this
area and load or overwrite system files. In addition, the URL for the
sub-directory is based on the domain of the site being used, so there is no
way for a form from one site to get access to data from other sites (sites
can share data across forms, though, which is very useful).

Typical uses are chaining forms together, where the output for one form is
the input to the next, or saving state across an application. An example of
the latter is illustrated in our Google Desktop app (see
ApplicationGoogleDesktopStoredSearches on the XForms Wiki) which allows you
to save searches across sessions.



INITIALISING THE LOCAL FILE
Whether using "file:" or "cookie:", a common situation is the need to create
the initial file on first use. This is a little tricky, because if you
initialise your instance using @src you have no way to detect that the file
doesn't exist. The following technique is used by our RSS Reader side-bar
(part of the formsPlayer install, and discussed at ApplicationRssReader):

1. First, create an instance that will hold the contents of the file. Give
it an inline instance of some default values--in our case it contains a
basic list of RSS feeds--rather than referring to the file using @src. In
the rest of this example, the instance is referred to as 'i-list'.


2. Set up a submission to load the document you want. In our case it's from
the "cookie:" protocol, but it could be from "file:":
 
  <xf:submission
   id="sub-open-list"
   method="get"
   ref="instance('i-list')"
   action="cookie://feed-list.xml"
   replace="instance"
  >
    <!--
      If we fail to load the list, then this is probably
      the first time we've been run, so save the default
      list.
    -->
    <xf:action ev:event="xforms-submit-error">
      <xf:message level="modal">
        RSS Reader has failed to open your local data file.
        This may be because this is the first time you have
        used the RSS Reader. A default data file will be
        created which includes a small number of feeds.
      </xf:message>
      <xf:send submission="sub-save-list" />
    </xf:action>
  </xf:submission>

Note the behaviour in the error handler (when the file doesn't exist)--we
simply save our initial instance data (inline in 'i-list').


3. Create an xforms-ready handler that triggers this get, i.e., loads your
local document:

  <xf:send submission="sub-open-list" ev:event="xforms-ready" />

(Note that you have now effectively emulated the behaviour of @src, but with
all the benefits of submission, such as events and the ability to use
instance data in the request.)

In normal operation this will cause the inline instance data to be
overwritten with the previously saved file, but on first use the error
handler will cause the inline instance data to be saved.


4. Set up a submission to save the list to the file (you don't need to use a
'dirty flag' but it is useful):

  <xf:submission
   id="sub-save-list"
   method="put"
   ref="instance('i-list')"
   action="cookie://feed-list.xml"
   replace="none"
   encoding="ISO-8859-1"
   omit-xml-declaration="false"
   indent="true"
  >
    <xf:setvalue bind="dirty-flag" ev:event="xforms-submit-done">
      false
    </xf:setvalue>
  </xf:submission>

Note that you would need the two submissions anyway, to load and save the
file; the only additional bit we're adding here is the use of xforms-ready
to invoke a load, and the use of xforms-submit-error on a load to invoke a
save.


USER-SPECIFIED URLs
The question of specifying a URL at run-time is less well defined. Again,
speaking only for formsPlayer, we have two ways of doing this, depending on
which version is in use. formsPlayer 1.x uses the xf:extension element to
allow control over all aspects of a submission, such as setting headers and
the target URL, whilst formsPlayer 2 uses a nicer looking technique,
attribute value templates.


FP 1
The main motivation for adding the ability to set all parts of a submission
is for things like blogging software using ATOM (for example). In this
situation you often want to be able to set the target of the submission to
something specific to the user, and also, you want to pass log-in
information in the request headers.

A SOAP request might be configured as follows:

  <xf:submission
   id="subSOAPRequest"
   ref="instance('iSOAPRequest')"
   method="post"
   action="http:ignore"
   replace="none"
  >
    <xf:extension>
      <sub>
        <action>
          <part value="instance('iScratch')/submission/@action" />
        </action>
        <headers>
          <header
           name="SOAPAction"
           value="concat(
             '&quot;http://schemas.xmlsoap.org/wsdl/http/',
             local-name(instance('iSOAPRequest')/soap:Body/*),
             '&quot;'
           )"
          />
        </headers>
      </sub>
    </xf:extension>
  </xf:submission>

The full example of a blogger is here:

 
<http://www.formsplayer.com/demo/web-services/atom-blogging/atom-blogger-com
.html>


FP 2
formsPlayer 2 introduces attribute value templates (AVT) in some attributes.
This is a technique used in XSLT, and simply allows you to obtain a value
from some node, rather than providing it literally. The above example in
formsPlayer 2 would become:

  <xf:submission
   id="subSOAPRequest"
   ref="instance('iSOAPRequest')"
   method="post"
   action="{instance('iScratch')/submission/@action}"
   replace="none"
  />


CHOOSING THE URI
Finally, whatever technique is used to get the URI into the submission, a
little trick you can use to allow the user to choose a file-name is to use
the xf:upload control:

  <xf:submission
   id="subSOAPRequest"
   ref="instance('i-data')"
   method="post"
   action="{instance('i-config')/submission/@action}"
   replace="none"
  />

  <xf:bind nodeset="instance('i-config')/submission/@action"
type="xsd:anyURI" />

  <xf:upload ref="instance('i-config')/submission/@action">
    <xf:label>Choose file</xf:label>
  </xf:upload>

By setting the datatype to xsd:anyURI we only obtain the URL of the
document, not the whole document.

Regards,

Mark


Mark Birbeck
CEO
x-port.net Ltd.

e: Mark.Birbeck@x-port.net
t: +44 (0) 20 7689 9232
w: http://www.formsPlayer.com/
b: http://internet-apps.blogspot.com/

Download our XForms processor from
http://www.formsPlayer.com/ 

> -----Original Message-----
> From: www-forms-request@w3.org 
> [mailto:www-forms-request@w3.org] On Behalf Of Flinton Adam
> Sent: 04 October 2005 14:52
> To: www-forms@w3.org
> Subject: Loading & saving documents
> 
> 
> Dear All,
> 
> I am looking to create a document editor for XML documents 
> based on a single schema using Xforms.
> 
> I have a host of questions but I'll fire them off one by one.
> 
> I would like to create a standalone editor if possible & I'd 
> like to be able to have an "open file" & then save/save as 
> functionality.
> 
> i.e. use IE + Novell plugin or possibly mozilla/firefox when 
> it's ready (or even OpenOffice possibly) to open an Xforms 
> document & then use it to populate it's model by opening 
> another xml file of the requisite structure/followng the 
> correct schema & then after editing the XML through the Xform 
> UI to do a save/save as.
> 
> Any ideas?
> 
> I can start off hosting the page/form itself within a jsp but 
> the files to be opened would always be on the user's local 
> disk & would need to be persisted back to that disk.
> 
> TIA
> 
> Adam
> 
> 
> This e-mail is confidential and privileged. If you are not 
> the intended recipient please accept our apologies; please do 
> not disclose, copy or distribute information in this e-mail 
> or take any action in reliance on its contents: to do so is 
> strictly prohibited and may be unlawful. Please inform us 
> that this message has gone astray before deleting it. Thank 
> you for your co-operation.
> 
> 
> 
> 

Received on Wednesday, 5 October 2005 10:56:43 UTC