XML UI: from XSD to XML

Mr. Ben "monkeyiq" Martin

Abstract

Exploration of creating XML documents from XSD schema files using a forms based interface is presented. An implementation using Gtk+ 1.3.11, libglade2 and ferriscreate is presented as a case study leading to future trends in XML user interface generation and style.


Table of Contents

What does XSD and XML do for the programmer
How does it all fit together
Ferris and ferriscreate
Obtaining and installing
Creation of an image
Creation of sockets
Relational databases
Text files
Multimedia
Summary of ferriscreate
Future trends
Bibliography

What does XSD and XML do for the programmer

From the programmers perspective, obtaining data from the user via a GUI form is a pain. Usually this is solved by the creation of two functions, one to create a GUI window and populate it, and another to save the data and destroy the UI. In this ad-hoc style the schema of what is edited is never made explicit. The rules governing what data must be present and the dependencies between the various information gathered are either not coded anywhere or are a wash with the GUI style information.

This document presents the process of obtaining information from the user as a somewhat more formal one. Within this new model the application presents an XSD [XSD W3C] file detailing what a legal document will be like, and then waits for XML [XML W3C] documents that can validate to that XSD file to act on. For example, to obtain the user name and password to login to a machine an XSD document would be created containing both of these as mandatory, and then via some means (in this document Gtk+ [GTK+]) that information is prompted from the user and a valid XML document formed and passed back to the application.

The obvious advantages of this are that the programmer of the login tool does not need to worry about the style of the interface at all or its customization. Style is all handled with XSL [XSL W3C] files. The second advantage is that the collection is easily changed, for example the user may decide to always login with his mobile phone. Using this example, the computer can talk to the mobile and as for a legal XML file from a given XSD.

Also, though this document details a Gtk+2 solution the very nature of the solution presented lends itself to ncurses [NCRS], ewl [EWL] and qt [QT] solutions and stylesheets.

How does it all fit together

When the application requires information it creates an XSD file and waits for an XML file in return. There are two XSL stylesheets used. The first XSL translates an XSD file into a libglade2 XML file. The second sheet transfers a libglade2 XML file into a XML file that will validate against the original XSD file.

The steps are thus

  1. Application generates XSD schema

  2. XSL translation on that XSD XML file into a libglade2 XML file

  3. libglade2 constructs GUI from libglade2 XML file

  4. When user actions dialog, libglade2 XML file (2) is created from existing UI.

  5. XSL translation is applied to libglade2 XML file (2) to create XML file that validates against XSD given in item i.

Of these the XSL file in item ii is the most interesting. With that XSL file the user can have additional information presented in the GUI, have possibilities limited from what the XSD file allows, or have freedom to move options around in the GUI layout as he sees fit.

Ferris and ferriscreate

A look at how this XSD, XSL, XML GUI solution was applied to a real word solution is now presented.

Ferris [FerrisWebSite] is a Virtual FileSystem (VFS) looking beast. Ferris aims to allow the user to mount anything and present a tree that is both a standard n-way tree of contexts (directories and files) and also each context has another dimension for Extra Attributes (EA). Because ferris is so happy to automount things there is less of a distinction between a file and a directory, for example an XML document is both a file (when read one gets the raw XML data) and a filesystem (the logical structure of the XML document). Ferris can mount Berkeley db [Berkeley DB], XML, sockets, mysql [MySQL], ftp and mbox among others.

Due to the complexity of ferris as a VFS a solution for "creation" of new contexts was not as trivial as using a creat(2) style function in the VFS. For example in the a mysql context viewing a table, to create a new context all the non null and primary key fields of the new tuple must be present at creation time.

Initially this was handled by passing in a context to the Context::createSubContext() method. Though this was always a dirty solution because each back end module had its own expectations for what it wanted in the context passed in. The solution was passable for clients that knew a prior which context they were dealing with. There was however a need for both explicit definition of what a context needed in order to create a subcontext, and for a generic creation tool.

The formal specification of what a context needs is solved with XSD, and generic context creation is done using ferriscreate. Using XSD to formalize what a context needs to make a new subcontext also allowed a context to change what it was needing and could use for the creation. for example the native filesystem module can ask for different data (preallocation) depending on what the underlying filesystem is for that path (eg. xfs).

Obtaining and installing

Ferris can be obtained at [FerrisWebSite]. Ferriscreate is also at that location in the ferriscreate cvs module. A release will be made shortly and when that occurs it will be listed in the witme.sf.net downloads section.

Ferriscreate requires ferris, Gtk+ 1.3.11, libxslt and libxml2 to be installed. Once the prerequisites are installed a standard
./configure
make
su -
make install
will get the executable installed. From there the xsl files in the src dir of the ferriscreate distribution need to be installed in your home dir;
mkdir -p ~/.ferriscreate;
cp src/*xsl ~/.ferriscreate;

Then the client can be run on the desired ferris context URL. Examples;

ferriscreate /tmp
ferriscreate x-sqlplus:/hostname/datebase
ferriscreate x-sqlplus:/hostname/datebase/table
ferriscreate socket:/tcp

Creation of an image

Other new possibilities were also allowed in the creation of new files. Taking as example the "New" from another Operating System, which allows one to create a new image of a type eg. "Bitmap Image" but the user can not control the exact creation of that image, making the whole process almost redundant.

With ferriscreate the user can select what type of file and also effect the creation with type specific data. For example the creation of a new png image can be done giving the name, width and height of that image among other data as seen in Figure 1. Using this style the user can create a new image file and then begin editing it right away (using for example the ego file manager to action an edit operation). This process effectively makes the open dialog of many applications redundant. The old style of application usage; opening the application, selecting new document from that applications menu, editing the new document and then selecting save as from the application menu is also set aside. In its place ferriscreate manufactures new objects and then an edit operation is performed on the existing object to invoke the users favorite tool for editing that type. Because the editing tool opened an existing file, the tool can also save back to that file, thus removing the need for the user to choose a location in a save as dialog.

Figure 1. Make png image

Notice that numeric type information is acquired using a spin button that can be adjusted in the XSD setting the min and max allowed values. The color space information is explicitly limited to a given Universe of Discourse (UoD) to avoid error. This UoD is obtained from the XSD in the form of a list type definition.

<simpleType name="ColorSpaceT">
    <restriction base="string">
        <enumeration value="RGB"/>
        <enumeration value="Gray"/>
        <enumeration value="YUV"/>
        <enumeration value="CMYK"/>
    </restriction>
</simpleType>
<simpleType name="ColorSpaceListT">
    <list itemType="ColorSpaceT"/>
    <restriction>
        <length value="1"/>
    </restriction>
</simpleType>
	

Creation of sockets

Socket creation was one VFS module that was expecting wildly different data in the Context::createSubContext() method. Depending on if the socket was a client or a server socket (connect or bind) different data was sought from the user. For example server sockets Figure 2 offer a limit on the number of connections that they will accept.

Figure 2. Make a new server socket

Various limits can also be formalized in the XSD, for example the socket port number can be made explicitly a 16 bit value, limits on the maximum number of connections allowed for the new server socket and a limiting range of values that are valid for the SSL version can be all made explicit in the XSD to help the VFS module to get legal data for a create operation.

Relational databases

Creating new tables in mysql using SQL syntax is usually a pain for even database centric kinds of people. Most of us do not create new tables in this manner often enough to commit the full syntax of the SQL CREATE statement to memory. By using XSL stylesheets to transform the XSD into a libglade2 XML file, various presentational widgets can be added to the GUI to help the user filling in the form. For example in Figure 3 the complete SQL create syntax for MySql is presented in a label widget. In the future a href widget may be present to allow the user to launch a web browser on the online MySql manual at the CREATE node.

Figure 3. Make a new table

Ferris also allows one to make virtual tables like views but which only exist inproc and are not persistent. Using this feature many little tables can be created for a short time only to serve data on specific queries. This is analogous to a RecordSet from a SQL SELECT in other database access APIs only the results are presented with the same VFS API as any other data. The select syntax is presented for the user to view in case a tricky select is required Figure 4.

Figure 4. Make a new temporary inproc SQL view

For a context that is displaying a mysql table, creation of a new subcontext means the creation of a new tuple in that table. Creation of tuple requires some fields to be present or the creation operation will fail. Also, the format of other fields needs to follow an explicit syntax but can not easily be fully enumerated. For example, There are only so many ways of storing color space information in mainstream use, though an SQL date field must follow a rigid syntax the universe of discourse is too large to explicitly enumerate. The solution to these problems is presented in Figure 5. All fields that are needed for the creation are explicitly marked by the XSD as such, and various SQL datatypes are augmented with hints for the form user.

Note that the SQL datatypes are explicitly defined in the XSD as such with

<simpleType name="SQLDateT">
    <restriction base="string">
    </restriction>
</simpleType>
	
so the XSL translation can easily pick out the SQL types and augment the display with hints for the user as to what information will be valid.

Figure 5. Make a new temporary inproc SQL view

Text files

The creation of new source files is explicitly supported in ferris Figure 6. At current only the desired License is sought. The source creation occurs by executing a shell script in the background and redirecting its output to the new file. Various information is defined in the environment of that shell script, for example, the path and rdn of the file and the first part of the filename without and dot characters. Using this environment information the shell script can produce include guards and other handy information. In future the ferris native module could check for the existence of a CVS directory when making the XSD and if it is present offer to add the new source file to cvs for the user at creation time. Also a CVS log message could be sought to use for the cvs add/commit operation.

Figure 6. Make a new C++ source file

Multimedia

Creation of multimedia is the next section for ferriscreate to spread into. Support at current is not as rich as it should be Figure 7. Plans for both audio and video creation include adding real time capture to the dialog. This would allow users to create a new mp3 file of a live guitar feed, or to capture a web cam and audio to a new file. Integration with streaming technology would also be a future trend, for example, capturing Internet radio web casts for later enjoyment.

Figure 7. Some new audio

Summary of ferriscreate

The ferris create example was a limited prototype that will evolve over time. There are some band aids in the example, for example the notebook labels have to be modified in C code after the GUI creation. I don't know if libglade allows setting notebook labels and at any rate I could not get any sane attempts to set the label from the libglade XML file. The solution in ferriscreate is to set the label of the notebook to the name of the first widget in that notebook. As the first widget is usually a layout widget this is a workable solution, though the path for the icon is currently set in the c++ source. The icon sought is sometimes based on the user preferences for a mime type, so interaction with ferris itself to find the name of that icon is needed. Such ferris interaction can not be done currently from either the XSL or libglade2 XML files.

To avoid some of the problems some sort of scripting language is needed in either the XSL or the libglade2 XML file itself. I am exploring the option to have a library above libglade2 that can execute scheme script from right out of the XML file. With this and a guile binding for Gtk+2 and a guile ferris binding the XSL stylesheets could be made much more powerful. For example, the contents of a entity in another XML file could be sought as the content of a gtktree.

Future trends

The ferriscreate example had some limitations and was a proof of concept and as such included both the dialog running code and much of the generics right in the executable instead of as a shared library. Code that should be shared includes the dialog runner, the XML and XSL handling code, and the code to dump out the Gtk+ GUI to a libglade2 XML file again. Abstraction of this code into a shared library will be a future project.

Many of the new Gtk+2 widgets are not usable directly to the libglade XML file. Though a gtktreeview and gtktreestore may be creatable from the libglade XML file they can not be directly populated. I hope to add some new Gtk+ types to the shared dialog running library to allow more gtk+2 widgets to be directly usable from the libglade file. For example, I will be creating a gtktreestore subclass that has a property for a content-url and maybe a inline-content, this will allow the libglade to set that property from the XML directly.

Exploration of scripting from within the XML file is on the cards. Current projects such as BML [BML] are being explored for ideas in this field. While I don't think writing large applications in this style to be common, hooking up Gtk signals to effect other parts of the GUI and to call scheme code to validate data would be very handy.

Presenting a drop down list of past XML documents in the dialog would be nice. Using this the user can reuse past form data or even have bookmarks to them so that favorite XML responses can be quickly selected. This would also help ferriscreate because it could have a history list for each logical type. Thus one could make a png image like the 4th last png made.

The creation of a web based version would be interesting. Though the model is more web than desktop centric I fear that the richness that even the current limited XSD examples from ferris provide would make a web based solution require much Javascript to compete with the Gtk+ widget solution.

For discussion about this document please use the Ferris mailing list .

Bibliography

Books