Getting xforms and eXist talking

I used three different methods for implementing XForms with eXist (I am currently only using #3).

  1. Orbeon Presentation Server
  2. An XQuery passed through a cocoon pipeline which transformed the XML results using an XSL stylesheet. The edited documents were saved to eXist using REST put.
  3. An XQuery that first authenticates the user and then outputs an xform using the retrieved document as the XForms instance and using REST put for submission.

I looked at Orbeon about 6 months ago, it seems like a great product, especially in light of the poor browser support for XForms. If I needed to make a commercially viable XForms application I would probably spend some more time playing with Orbeon. However, I felt that Orbeon added yet another layer of complication to my application and it was not necessary in our situation because our XForms are being used in a controlled environment (and I don’t have more time). I can be assured that everyone using the editing interface will be using Firefox, not a great solution, but so far so good.

I generally prefer XSL to XQuery, so my XQueries have, in the past been pretty simple, returning very raw results to an XSL stylesheet. My first attempt at XForms used XQuery to call the XML document to be edited (or to create a new document). Then I had a cocoon pipeline  to specify the XSL stylesheet for transformation and the serialization option.

<map:match pattern="getDC.xq">
  <map:generate src="getDC.xq" type="xquery"/>
  <map:transform src="stylesheets/dcForms.xsl"/>
  <map:serialize type="xhtml11"/>
</map:match>

In the main sitemap.xmap file (included with exist), xhtml11 is the serializer that will output mime-type=”application/xhtml+xml”.

The XSL stylesheet then selects the node I’m interested in and uses xsl:copy to populate the XForms instance. The submission element uses put to replace the existing document with the edited document.

<xf:model>
  <xf:instance id="metadata">
    <xsl:copy-of select="/child::*"/>
  </xf:instance>

  <xf:submission id="submit" method="put" replace="all">
    <xsl:attribute name="action">
      <xsl:value-of   select="concat
           ('/exist/servlet/db/mets/collections/',
           $filename,'.mets.xml')"/>
    </xsl:attribute>
  </xf:submission>

</xf:model>

One of the features that I found the most useful in XForms is the ability to repeat elements as needed. Here is an example from a very simple form that we used to edit Dublin Core records that uses XForms repeat. This field populates the dc:subject element and adds a type attribute selected from a drop down menu. New subject elements are added or deleted when the users click the add or delete buttons created by xf:trigger. I use xf:setvalue to create each new element as a blank element, otherwise the element will simply copy the data from the first instance of the element.

<xf:repeat id="repeat.subject" nodeset="//dc:subject">
  <xf:input ref=".">
   <xf:label>Subject Headings:</xf:label>
  </xf:input>

  <xf:select1 ref="@type">
   <xf:label>Type: </xf:label>
   <xf:item>
    <xf:label>topic</xf:label>
    <xf:value>topic</xf:value>
   </xf:item>
   <xf:item>
    <xf:label>name</xf:label>
    <xf:value>name</xf:value>
   </xf:item>
  </xf:select1>
 <xf:trigger class="delete" appearance="minimal">
    <xf:label>Remove</xf:label>
    <xf:action ev:event="DOMActivate">
     <xf:delete nodeset="instance('metadata')//dc:subject"
         at="index('repeat.subject')"/>
    </xf:action>
  </xf:trigger>
 <xf:trigger class="add" appearance="minimal">
    <xf:label>Add a subject field</xf:label>
    <xf:action ev:event="DOMActivate">
      <xf:insert nodeset="instance('metadata')//dc:subject"
           at="index('repeat.subject')" position="after"/>
      <xf:setvalue ref="instance('metadata')//dc:subject[last()]" value=""/>
    </xf:action>
  </xf:trigger>
</xf:repeat>

This method works fine, but I as stated in an earlier post I wanted to route all my metadata processing XQueries through a password authenticating XQuery. This query calls a series of metadata administrative tasks, including the XForms.

I added the following namespaces for XForms to my xquery:

declare namespace xf="http://www.w3.org/2002/xforms";
declare namespace ev="http://www.w3.org/2001/xml-events";

And the exist:serialize option:

declare option exist:serialize "method=xhtml media-type=application/xhtml+xml";

The XForm is contained in a function called by an authenticating function. I made very few changes to the XForm code I had been using in my XSL stylesheets to get it working when called by the XQuery.

Here is a round-up of some of the resources I have found to be most useful in building these forms:

  1. eXist mailing list – search the archives for XForms
  2. eXist – XQuery examples
  3. Cocoon website (pipelines)
  4. XForms tutorial – Adrian de Jonge’s blog
  5. XForms – Tutorials and Cookbook – Wikibooks
  6. XForms for HTML Authors – W3C
  7. O’Reilly XForms Essentials by Micah Dubinko
Advertisements

14 Responses to “Getting xforms and eXist talking”

  1. ksclarke Says:

    Sounds very interesting! Do you have a demo online for the third approach?

    I also wonder whether you’ve looked at client side libraries for doing this so that there isn’t the Firefox dependency (though I understand this isn’t a problem for you since you have an in house group of users).

  2. wsalesky Says:

    Thanks for the link, this looks pretty interesting.

    I do have a some forms working online, we are actually using them in production. If you are interested in seeing an example form, I can send you a link and password (but first I need to set up a guest account and password).

    However, I just installed FireFox 2.0 and the XForms extension does not work with it. Also I believe the main developer for the XForms extension has been laid off, so I’m feeling a little less happy about relying on this extension.

    If you have not installed FireFox 2.0 and want to take a look at the forms let me know.

  3. ebruchez Says:

    Thanks for the kind words about Orbeon. Just in case, the latest version of the DMV Forms example at http://www.orbeon.com/ops/forms uses XForms 1.1’s REST capabilities to target eXist directly.

    -Erik

  4. Alessandro Vernet (web forms) Says:

    eXist is also pretty popular amongst Orbeon users. I work on the Orbeon code, and develop custom applications for customers using our open-source Orbeon product. We ended-up using eXist for a number of applications. You are right: XForms and eXist play very well together.

    One thing I really like is using the XForms submission replace=”instance” to directly query eXist. For simple things (getting a document, updating a document, simple queries), this gets rid of a whole layer in the middle. This means less code to understand, write, and maintain.

    Maybe this is not a good idea when using a browser-based XForms implementation, as you will have to make the database accessible from your clients. But with a server-side implementation, the XForms code stays on the server, so queries stay on the server. The end-user can’t just change some XForms and run another query in your database. So you can afford to query eXist directly from XForms without compromising security.

    Alex

  5. wsalesky Says:

    Hi Erik,
    Thanks for the info. I’ll take a look at that example.

  6. wsalesky Says:

    Alessandro.
    I think the XForms submission replace=”instance” would be a more elegant solution for many of my forms than the replace=”all”and I’m in favor of less code to write and maintain.

    Thanks for the comment.

  7. Alessandro Vernet (web forms) Says:

    Sounds good. Let us know how it works if you get to try the replace=”instance” method.

    Alex

  8. Chris Wallace Says:

    Just wanted to say thanks for your helpful blogging on your work and point to some teaching material I’m putting together for XForms with eXist at

    http://www.cems.uwe.ac.uk/chriswallace/xforms/index.html

    which links to your blog. We are just starting to implement XForms for update to our faculty information system based on eXist.

  9. wsalesky Says:

    Hi Chris,
    I’m happy to hear that the blog has been helpful, I know I find examples/tips from other implementors invaluable when starting off with a new technology. Thanks for the link, I have found some good examples and tips from the blogs and tutorials you have listed. You might also add mailing lists or forums to your page, I have found them to be really helpful. (The Orbeon users list, the W3C XForms forum and also this one: http://groups-beta.google.com/group/mozilla.dev.tech.xforms/topics )

    -WS

  10. ilango gurusamy Says:

    Hi
    Do you have examples for #1 (Orbeon Presentation Server).
    Also could I see an example form running on your server. Thanks very much for your kindness.

  11. ilango gurusamy Says:

    Oh, Yes, I would like to see an example for # 3 as well.

  12. wsalesky Says:

    Ilangno,
    For samples of Orbeon forms I would recommend taking a look at the Orbeon web site. they have a lot of examples. You should be able to plug the sample form (Solr,) into an Orbeon installation. I can’t provide access to the forms I’m currently running, as they are behind a firewall. The only difference between the forms that I use in production and the forms I’ve posted as examples are that my production forms are generated using xquery, and submit data to both my eXist instance and my Solr index.

    Here are links to several other sample forms I’ve worked on, you can also find plenty of xform examples on the Orbeon site, wikipedia and elsewhere.

    Dublin Core Form
    MODS Form

    Hope that helps,
    -Winona

  13. ilango gurusamy Says:

    Thank you. It helps

  14. ilango gurusamy Says:

    Alessandro
    Could you throw more light on your statement
    “One thing I really like is using the XForms submission replace=”instance” to directly query eXist. For simple things (getting a document, updating a document, simple queries), this gets rid of a whole layer in the middle. This means less code to understand, write, and maintain.”

    thanks

Comments are closed.


%d bloggers like this: