Menu

Editing XML Data Using XUpdate and HTML Forms

June 12, 2002

Chimezie Ogbuji

In this article I will discuss how XUpdate can be used in conjunction with XSLT to write tools for authors of web-based applications that will automatically generate HTML forms for editing various kinds of data. Forms are the primary means that web-based applications collect information from a user. XML, XUpdate, XSLT can be employed to automate this process for arbitrary data types.

Introduction

Most web applications that require a substantial amount of data from the user agent will have to deal with fashioning HTML forms for this purpose. This is a very common scenario, and authors will find themselves often repeating certain patterns in the form elements used for various types of data. For example, data entry fields where the value is restricted to a range of values are often rendered using selection form elements, and in situations where large amounts of text input is required, a textarea is often employed. These common patterns are often abstracted by developing templates for specific data

1.  Introduction
2.  XUpdate
3.  Specifying the application data schema
3.1.  Common data fields
3.2.  Larger text data fields
3.3.  Boolean data fields
3.4.  List-type data fields.
4.  Transforming application data to HTML forms
4.1.  The source document.
4.2.  The stylesheet
4.3.  The data templates
4.4.  The resulting form
5.  Transforming form data to XUpdate documents
5.1.  Routing form data to the stylesheet.
5.2.  XUpdates per data type
6.  Conclusion
7.  Resources

This is especially true among XML applications, i.e., applications that depend on XML or XML-related technologies for data storage, knowledge management, or implementation. The structured nature of XML serves to cause certain data patterns to repeat themselves in most situations.

The most common of these patterns can be identified and abstracted into an XML schema. Web developers can then model their data as instances of this schema and use two stylesheets (detailed later in the article) to transform the document instances into HTML forms for editing the specified data and process data from a submitted form and generate an XUpdate document for updating the data.

XUpdate

XUpdate is an XML language for updating arbitrary XML documents. XUpdate makes heavy use of XPath for selecting a set of nodes to modify or remove. XUpdate was the obvious choice to use for updating our arbitrary data documents. And we will be writing a stylesheet which generates XUpdate documents that can be used to update XML application data automatically. The reader should briefly review the specification to refresh her or his knowledge of XUpdate syntax.

Specifying the application data schema

In order to abstract data such that we can generate forms automatically for its modification, we need to look at some common scenarios where data is entered into an HTML form. Consider a contact manager that provides a screen for editing the properties of a user. The application will probably want the name of the user and some contact information (email, homepage, etc.). These are all single entry data fields.

Common data fields

In order to abstract data enough to automatically generate forms for its modification, we need to look at some common scenarios where data is entered into an HTML form to an application. Consider a contact manager that provides a screen for editing the properties of a user. The application will probably want the name of the user and some contact information (email, homepage, etc.). These are all single entry data fields.

  • name: [ name of the user ]
  • email: [ email of the user ]
  • homepage: [ homepage of the user ]

These are simply name-value pairs.

First, let's define a namespace for this schema, http://chimezie.ogbuji.net/xml/EditableData/. We will use an element in this namespace named Object, which will represent the abstract object being edited. The element will have a "name" attribute, which is a name associated with the object. We will also have an Entry child element for each name-value pair. In our mythical contact manager, the editable data for a user object will be represented by the following document:


<Object xmlns="http://chimezie.ogbuji.net/xml/EditableData/"

        name="Chimezie Ogbuji">

  <Entry key="name">Chimezie Ogbuji</Entry>

  <Entry key="email">chimezie@ogbuji.net</Entry>cnn

  <Entry key="homepage">http://chimezie.ogbuji.net</Entry>

</Object>

Larger text data fields

Often simple text data is alternatively edited using a text area form element. The main distinction in this case is usually the amount of text being assigned. We will be distinguishing this kind of data by abstracting it with a LargeEntry element.

For instance, consider an entry for the user's biography. This usually consists of one or a few paragraphs, and it would typically be edited with a textarea. Following the schema we have developed so far, we can serialize a user with the previously defined data fields as well as an entry for his or her biography as follows:


<Object xmlns="http://chimezie.ogbuji.net/xml/EditableData/" 

        name="Chimezie Ogbuji">

  <Entry key="name">Chimezie Ogbuji</Entry>

  <Entry key="email">chimezie@ogbuji.net</Entry>

  <Entry key="homepage">http://chimezie.ogbuji.net</Entry>

  <LargeEntryType name="biography">Chimezie Ogbuji is software

    developer with a bachelors degree in Computer Engineering.

    He is currently a contractor for Fourthought Inc.

  </LargeEntryType>

</Object>

Boolean data fields

Another data type used in common form inputs is the checkbox. This usually represents a labeled boolean value. Let's consider a boolean value which specifies whether a user is an administrator of the application. Following our schema convention, we could model this value like the following.


<Object xmlns="http://chimezie.ogbuji.net/xml/EditableData/"

  name="Chimezie Ogbuji">

  <Entry key="name">Chimezie Ogbuji</Entry>

  <Entry key="email">chimezie@ogbuji.net</Entry>

  <Entry key="homepage">http://chimezie.ogbuji.net</Entry>

  <LargeEntryType name="biography">Chimezie Ogbuji is software

    developer with a bachelors degree in Computer Engineering.

    He is currently a contractor for Fourthought Inc.

  </LargeEntryType>

  <Boolean key='administrator' value='1' />

</Object>

In this case, we use a number to represent the boolean value of the entry (which could take the value of 1 or 0), indicating that the user Chimezie Ogbuji is an administrator.

List-type data fields.

The other common data-type entered from a form is a list of values from which one or more is selected. Consider an entry for a user's age range:

  • 12 - 18
  • 19 - 35
  • 36 - 50
  • 51 - up

This data type needs to be abstracted into a set of elements to represent an instance. For our elements, we will try to use names already associated with the form element. In this case we will have a List and an Option element to represent these kinds of data fields.


<Object xmlns="http://chimezie.ogbuji.net/xml/EditableData/"

  name="Chimezie Ogbuji">

  <Entry key="name">Chimezie Ogbuji</Entry>

  <Entry key="email">chimezie@ogbuji.net</Entry>

  <Entry key="homepage">http://chimezie.ogbuji.net</Entry>

  <LargeEntryType name="biography">Chimezie Ogbuji is software

    developer with a bachelors degree in Computer Engineering.

    He is currently a contractor for Fourthought Inc.

  </LargeEntryType>

  <List name="Age">

    <Option label="Juvenile">12 - 18</Option>

    <Option label="Young adult" select="1">19 - 35</Option>

    <Option label="Middle aged adult">36 - 50</Option>

    <Option label="Senior citizen">51 - up</Option>

  </List>

  <Boolean key="administrator" value="1"/>

</Object>

We define an "age" data range and specify that Chimezie Ogbuji's age range is 19-35 (Young Adult). Notice, other instances may have multiple Option elements with "select" attributes set to 1. This doesn't make sense in this situation, since the age ranges are mutually exclusive. We could have chosen to make this distinction explicit by defining a "multiple" attribute on the List element.

Transforming application data to HTML forms

The source document.

Now that a schema has been defined for arbitrary editable data, we can begin to look at transforming instances of this schema into HTML forms for editing the same data. First, we will assign specific form elements to data fields.

  • Entry data - Text INPUT elements
  • Large data - TEXTAREA elements
  • List data - SELECT and OPTION elements
  • Boolean data - Checkbox INPUT elements.

We will be using the instance of the schema that we developed through the earlier examples for the XML source. The schema can be retrieved here. You can also get the XML of the example instance here.

The stylesheet

The stylesheet will take an instance of our editable XML schema and generate forms for editing the data. It uses the form elements (from our list above) where appropriate, with labels to identify each data entry.

Let's take a look at the top level templates to see how the form is setup:


<xsl:stylesheet version="1.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

  xmlns:edXml="http://chimezie.ogbuji.net/xml/EditableData/">

  <xsl:output method="xml" version="1.0" 

              encoding="UTF-8" indent="yes"/>

  <xsl:template match="edXml:Object">

    <table>

      <caption>Editing: <i>

         <xsl:value-of select="@name"/></i></caption>

      <xsl:apply-templates select="edXml:Entry | 

                   edXml:Boolean | edXml:List  | edXml:LargeEntry"/>

      <tr>

        <td/>

        <th align="center">

          <input type="submit" value="Change {@name}"/>

        </th>

      </tr>

    </table>

  </xsl:template>

  .... snip ...

</xsl:stylesheet>

The Object element is matched and the HTML for a table is created in the result tree. The table has a caption identifying the object being edited by name. The stylesheet then instructs the processor to matches the elements for the 4 data types (as defined previously in our schema).

There will be templates for each data type in order to render them appropriately. A submit button is created at the bottom of the table.

The data templates

We'll now take a closer look at one of the matching templates. In particular, we will pay close attention to the template that matches List elements. These are the more involved data structures which are rendered using SELECT and OPTION form elements.


<xsl:template match="edXml:List">

  <tr>

    <th align="right">

      <xsl:value-of select="@name"/>

    </th>

    <td>

      <select name="input-{@name}">

        <xsl:for-each select="edXml:Option">

          <xsl:element name="option">

            <xsl:attribute name="value">

              <xsl:value-of select="."/>

            </xsl:attribute>

            <xsl:attribute name="name">

              <xsl:text>input-</xsl:text>

              <xsl:value-of select="@name"/>

            </xsl:attribute>

            <xsl:if test="boolean(number(@selected))">

              <xsl:attribute name="selected">on</xsl:attribute>

            </xsl:if>

            <xsl:value-of select="@label"/>

          </xsl:element>

        </xsl:for-each>

      </select>

    </td>

  </tr>

</xsl:template>

First, notice we put a header cell with the name of the data in the result tree. Then we create the SELECT and OPTION elements, using the structure of the source document to determine how they are rendered. We use an arbitrary convention for the input names: we append 'input-' to their names (as specified in the source instance).

The resulting form

The template only generates the HTML for the table and the form inputs. The idea is for the form body itself (as well as the rest of whatever is to be displayed in addition to the automatically generated forms) to be provided previously. The template is evoked to fill the remaining HTML. The resulting transformation results in HTML like the following.

Browser form

Transforming form data to XUpdate documents

Finally, we need to discuss how a template can be fashioned to take the generated names of the form inputs as top-level parameters and generate an XUpdate document. This XUpdate document can be applied against the original instance of the editable XML schema in order to reflect the modifications specified by the agent.

Routing form data to the stylesheet.

Depending on the application, the POSTed form data can be redirected to a stylesheet in many ways. If an application server is being used, it can pass the form data as the source for the transformation or through some other external means (top-level parameters or extension functions/elements).

The latter option is the way 4Suite works. We leave this detail to the application developer and simply outline examples of XUpdate documents that are generated from various scenarios.

XUpdates per data type

Consider the following scenarios:

  • The user agent changes the biography entry only.
  • The user agent changes the biography and age entries.
  • The user agent changes the administrator entry value to "true"

In the first case, assuming the user agent removes the last name of the user (Ogbuji, in this case) from the biography, the resulting XUpdate document would be


<xupdate:modifications 

  version="1.0"

  xmlns:xupdate="http://www.xmldb.org/xupdate"

  xmlns:edXml="http://chimezie.ogbuji.net/xml/EditableData/">

  <xupdate:update 

    select="//edXml:Object/edXml:LargeEntry[@name = 'biography']">

    Chimezie is software developer with a bachelors degree

    in Computer Engineering.  He is currently a contractor

    for Fourthought Inc.

  </xupdate:update>

</xupdate:modifications>

In the second scenario, we will assume the biography is changed in the same way and the age entry is changed to the third option (Middle aged adult). The corresponding XUpdate document would look like


<xupdate:modifications 

  version="1.0"

  xmlns:xupdate="http://www.xmldb.org/xupdate"

  xmlns:edXml="http://chimezie.ogbuji.net/xml/EditableData/">

  <xupdate:update

    select="//edXml:Object/edXml:LargeEntry[@name = 'biography']">

    Chimezie is software developer with a bachelors degree

    in Computer Engineering.  He is currently a contractor

    for Fourthought Inc.

  </xupdate:update>

  <xupdate:remove 

    select="//edXml:Object/edXml:List[@name = 'age']/

            edXml:Option[@label = 'Young adult']/@select"/>

  <xupdate:update 

    select="//edXml:Object/edXml:List[@name = 'age']/

            edXml:Option[@label = 'Middle aged adult']/@select">

    1

  </xupdate:update>

</xupdate:modifications>

This document starts off like the previous once because the same change is applied to the biography entry. However, there are two new xupdate elements. The first matches the Option element (in the instance of our schema), which represented the old selection, and removes the "select" attribute. It then adds a "select" attribute (with a value of 1) to the Option element representing the new selection, essentially toggling the selection from the old value to the new.

Finally, the last scenario involves the modification of a Boolean data-type (rendered as radio inputs with values of "true" or "false"). This involves a simple modification of the "value" attribute on the corresponding Boolean element. The XUpdate document generated would look like


<xupdate:modifications 

  version="1.0"

  xmlns:xupdate="http://www.xmldb.org/xupdate"

  xmlns:edXml="http://chimezie.ogbuji.net/xml/EditableData/">

  <xupdate:update 

    select="//edXml:Object/edXml:Boolean[@key = 'biography']/@value">

    1

  </xupdate:update>  

</xupdate:modifications>

Conclusion

The editable data XML schema we have defined here is abstract enough to be a sufficient representation of arbitrary application data. However, it isn't practical to assume that it will be the best XML schema for any given situation. In most cases, the application developer would want to transform XML data from a specific format to this editable data XML schema, generate form HTML, collect the modifications, and transform the instance back to the original format.

These two very simple stylesheets can save a significant amount of work to create repetitive HTML for forms. For other tangential considerations, the user should take a look at the W3C's XForms 1.0 Working Draft: http://www.w3.org/TR/xforms/, which proposes a platform-independent way to specify user interface forms by separating the data model from presentation information.

Resources