previous article on XForms in OpenOffice
showed how to create a simple XForm in OpenOffice. My introduction to this particular technology came while working on the Danish UBL
project, which needed a cross-platform implementation for some of the 23 UBL 2.0 document types
intended for use by small businesses.
The project initially supported only three types: Invoice
, and Order
, but had a stated goal of supporting all the UBL formats.
Unfortunately, it proved impossible to create this solution purely in XForms in OpenOffice. The project required supporting documents containing all possible elements, but the UBL Order implementation ran into performance problems, because, as described in the previous article, it keeps every binding in memory; therefore, a large number of bindings slows down the implementation measurably. Obviously, the complexity of expressions can also affect this. In my experience, forms that exceed several hundred bindings are unusable.
A 10-line UBL Order was likely to have 500 or more bindings, and thus was not usable in an OpenOffice XForm. Nonetheless, the route to discovering this depressing information did produce some useful tools and techniques for others who want to work with smaller XML documents in OpenOffice.
Importing XML Formats into OpenOffice
Because OpenOffice's internal representation is ODF XML, it is natural to generate ODF from other XML formats using an XSLT transformation. This applies equally well to an XForm inside of an ODF document.
|Author's Note: To work with the code in this article, you need OpenOffice version 2.4 (earlier versions not tested) with the Java runtime enabled. The OpenOffice XSLT implementation currently uses Xalan as its XSLT processor. However, as this article was being prepared for publication it was announced that OpenOffice 3.1 will use Saxon, which will allow future filters to be written using XSLT 2.0. The sample filter uses XSLT 1.0, because that's the XSLT version supported in the current OpenOffice release.
You always need to take a few things into account when making an XSLT transform, such as the processor and the context (web server, command line application, etc.). OpenOffice adds yet another consideration: You have the possibility of running the transformation as an XSLT Filter
. An XSLT Filter combines an XSLT stylesheet and some OpenOffice settings registered in OpenOffice that allows OpenOffice to open various XML-based formats and work with them in the context of the application.
This article explains how to create an OpenOffice XSLT Filter that applies generically to all example XML instances—in other words, it's as a basic tool for working with XML in OpenOffice XForms.
What the Filter Should Do
|Figure 1. Generic XSLT Model: The generic XSLT filter generates ODF instances from any number of input formats.|
A generic filter should be able to accept any input XML, and generate an XForm and the OpenOffice form fields and bindings to allow users to edit that XML, excluding mixed content formats which are not suited to form based editing. Because it is generic, you can reuse it within other filters for specific formats (see Figure 1
While the model looks simple, the implementation is far more difficult. Remember that the content in an OpenOffice XForm is separated in several sections. The Form fields, bindings, and XML instance are in different parts of the document, but they all need to be able to point back at each other, as shown in Figure 2.
|Figure 2. OpenOffice XForms Relationships: The diagram shows how the different parts of the OpenOffice XForms implementation relate to each other.|
To build these relationships, the transform uses three different modes
, because it must process the same input tree three different times.
There are other filter processing limitations as well. For example, OpenOffice restricts you to using Xerces, its built in processor, which limits you to XSLT 1.0. However, you could run the XSLT stylesheet outside of OpenOffice, using a different parser, and then use another process to assemble the zipped OpenOffice document from the generated ODF with XForms document.
|Figure 3. Format-Specific Transform: Input format #4 uses a format-specific transformation, but includes the Generic XSLT transform as a library to enable the transform.|
Generic solutions often suffer from reusability problems; the twists and turns that make the solution generic may also make them unsuitable for specific solutions. That's not true here. This transform should work in conjunction with any specific format transformation to generate a generic ODF document with an embedded XForm as shown in Figure 3
Generic Transform Limitations
Because the generic solution must accept any input for which an XForms model can be generated, it generates primarily text field form elements. A transformation written to use XML Schema to generate XForm bindings would be able to use the schema type information to determine that an input field should be a radio button or some other control, but when generating an XForm from a sample input without a schema transformations are limited to generating text fields.
To make sure that form fields get output in appropriate locations, the transform places controls relative to the paragraphs that contain them, using the text:anchor-type attribute. Among other benefits, this frees the process from having to calculate X and Y coordinates for the controls.