XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

XML Forms, Web Services and Apache Cocoon
by Ivelin Ivanov | Pages: 1, 2, 3

Providing Model Data

The client browser will collect input from the user and will directly submit the data as HTTP GET or HTTP POST parameters.

XMLForm processing keeps track of the state of the partially filled form through this model data. Initial values for the model may be provided or not. The model essentially holds a JavaBean or a skeleton XML document that gets updated as the user fills out the form. It gives the author full control on the structure of the submitted data. When the form is submitted, the input is serialized as HTTP GET or POST parameters.

This design has features worth noting:

  • There is complete flexibility in the structure of the model data for both JavaBean and XML models, including the use of element attributes.
  • Empty elements roles and hobbies serve as place-holders in the JavaBean structure and will be filled in with form data provided by the user.
  • An initial value for the form control is provided through the model; in this case first name, last name, email, and age. In the submitted data, the initial values will be replaced by the user input, if the user changes the form control displaying that data.

To connect the model with form controls, the ref attributes on the form controls need to point to the proper part of the model data, using binding expressions:

Example 3. Binding Form Controls to Model Nodes with ref

                ...
                <xf:textbox ref="firstName">
                ...
                <xf:textbox ref="/email">
                ...

Binding expressions are based on XPath, including the use of the @ character to refer to attributes, as we will see later. Note that for illustrative purposes, the first two expressions make use of the XPath context node, which defaults to the top-level element. The third and forth expressions show an absolute path.

Form processing

As we discussed earlier, an Action is a controller component responsible for processing user input, possibly updating the domain model, and selecting the next view for the client. An XMLForm Action class is an Action which automatically populates the form model with the input values, as specified by the binding ref attributes on the elements in a form documents.

Participating Classes

Let's look at the structure of an XMLForm Action and its associations.

Form Processing Class Diagram
Figure 4. Form Processing Class Diagram

Following is a short description for each of the key methods of an XML Form:

  • perform() is invoked after the model is populated with request parameters and usually validated by a schema. It's responsible for implementing the navigational logic by interacting with business logic components and inspecting the state of the Form model.
  • getFormView() returns the value of the Form view name. Each XMLForm document specifies the ID of the form it is referring to and the name of the page view it is used in.
  • getCommand() returns the ID of the action button pressed by the user. The Action class can use this method in combination with getFormView() to determine the next page for the user.
  • prepare() can be optionally implemented to handle "Cancel" buttons or unselected check boxes. It is invoked before the form model is populated with request parameters.
  • getFormId() can be optionally implemented to provide the unique ID for an XMLForm instance. Each XMLForm instance must have its unique ID within the application. The form key is used to store the form instance in the Servlet Request or Session. It is referenced by this key also in the id attribute of the XML form elements.
  • getFormScope() can be optionally implemented to specify the storage scope for the XMLForm instance. Each XMLForm instance is stored in either the Servlet Request or Session for reference by the XMLForm view documents or other application modules.
  • getFormValidator() can be optionally implemented to provide the model Validator. Each XMLForm instance can have a Validator which is automatically applied against the model after it has been populated with new data. The result of a validation is held in the Form instance along with the model. Further in the pipeline the XMLForm view documents can access the form instance model and its violations.

Class Interaction

We skimmed the surface of the class structure, now it's time to get acquainted with the interactions between the classes. The following diagram illustrates the sequence of calls which take place when an HTTP request is made to an XMLForm Action.

Form processing sequence
Figure 5. Form processing sequence

A servlet request is first handed to the XMLForm Action. The action may choose to interrupt further processing in its prepare() method, depending on the request parameters or some other business rules. If it decides to continue, the action will pass the servlet request to the Form instance, which in turn automatically populates the associated model. Next the form uses the Validator to test the state of the model corresponding to the current form view. As a result the Form holds the model populated with new data, accompanied by a set of violations, possibly empty.

Control is then given to the perform() method, which is the essence of each XMLForm action. This is where the workflow rules for a Form instance are executed. The implementation depends on the needs of each concrete application. At the end of its work, the method will return either null, prohibiting further pipeline steps within the corresponding <map:act> section, or a Map object, which has at least one key-value pair of the form ("page", nextPageName), where the value of nextPageName is a logical name of the next page for the user.

XMLForm markup

XMLForm implements the majority of Form Controls defined in the W3C XForms specification.

A Form Control is: An XForms user interface control that serves as a point of user interaction.

Form controls enable accessibility by taking a uniform approach to labels, help text, navigation, data input, and so on. Internationalization issues are addressed by following the same design principles as XHTML. Cocoon's i18n markup is a natural match for the XMLForm input markup. All form controls are suitable for styling as aural or visual media.

When rendered, form controls display the underlying data values to which they are bound. While the data presented to the user through a form control must directly correspond to the bound instance data, the display representation is not required to match the lexical value. For example, user agents should apply appropriate conventions to the display of dates, times, durations, and numeric values including separator characters.

Form controls encapsulate high-level semantics without sacrificing the ability to deliver real implementations. For instance, form controls select and select1 enable the user to select one or more items from a set. These form controls distinguish the functional aspects of the underlying control from the presentational and behavioral aspects. This separation enables the expression of the intent without detailing how it will be fulfilled.

For detailed description of each form control, consult the W3C XForms specification

Transforming XMLForm Documents to Presentation Languages

XForms and XMLForm allow the web developer to focus on the workflow and declaratively specify the intent of each input page. Without XForms, developers are both coding the page navigation and dealing with the constantly growing browser-specific issues. There are normally two or more transformations before a raw XMLForm document is rendered into a client hosted language. The first is to populate the form controls with the values of the model properties which they reference. This stage also unrolls repeat-like elements into single elements addressing individual model properties. The second stage is optional and depends on the client host. If it is a typical HTML browser, the second stage will apply an XSLT transformation which converts XMLForm tags into corresponding HTML tags. Additional stages may be involved to resolve internationalization tags or other application specific tags.

XMLFormTransformer: Populating model values in XMLForm tags

When writing an XMLForm document, an author uses static constructs with references to model properties. It is the job of the XMLFormTransformer to populate the actual model values into the author specified form controls. XMLFormTransofmer is a relatively complex component. We will try to provide enough examples to illustrate its work.

Transforming the textbox element

Here is an example of a textbox form control as it appears in the original document, followed by the output of the transformation.

Example 4. textbox element in the original document

 ...
<xf:textbox ref="/firstName">
  <xf:caption>First Name</xf:caption>
  <xf:violations class="error"/>
</xf:textbox>
...

Example 5. textbox element after transformation

...
<xf:textbox ref="/firstName">
  <xf:value>abc</xf:value>
  <xf:caption>First Name</xf:caption>
  <xf:violation class="error">First name should be at 
  least 4 characters.</xf:violation>
</xf:textbox>  
...

From these XML snippets, you can see how an additional value element was added to the textbox. Also the violations tag was replaced by a violation tag with an error message related to the value of the firstName model property.

Pages: 1, 2, 3

Next Pagearrow