A Very Swish XML Editor

Steve Ball


Table of Contents

Abstract
Introduction
TclXML
TclDOM
Megawidgets
Plugin Architecture
TclSOAP - "Home And Away"
Conclusion

Abstract

Although it is possible to read and modify XML documents using a plain text editor, most authors of documents would prefer to edit their documents at a higher level of abstraction than working with the raw XML syntax. Different authors will require different views of their documents, or even of the same document. A fully-featured editor must therefore provide more than just basic editing facilities; for example, the ability to visualise the document's information content, interact with the document type's schema and high-level, application-specific content manipulation.

Zveno's Swish XML editor aims to provide not just basic editing functions, but a platform for building content visualisation facilities and application-specific editing features for vertical markets. Swish is built upon a number of low-level packages, and thus may be seen as an editing toolkit rather than an individual editor. The lowest-level packages each implement a Web standard, such as the XML Infoset, DOM and SOAP, which are then combined into middle-level packages, such as DOM-aware megawidgets. Swish integrates these packages at the highest-level into the editor application.

In order to be able to operate on various different platforms, Swish is written in Tcl/Tk, an excellent scripting language and windowing toolkit which allows rapid, cross-platform software development, as well as integration with other languages, in particular Java.

Introduction

Authoring XML documents can be achieved using not much more than a simple text editor. However, even experienced programmers and authors can easily introduce syntax errors into their documents with manual editing of XML markup. Most authors are not concerned with the fact that they are creating XML documents; they simply want to concentrate on the task at hand, creating information. Thus XML editing applications that help the author to create well-formed, perhaps even valid, XML documents are required for all levels of author sophistication.

Some existing XML editors, such as XML Spy[XMLSpy00], expose the XML syntax to the author. These type of XML editors do not provide a very high level of abstraction from the XML syntax; they are little more than a thin veneer, ensuring that the XML created is well-formed but not making the process of managing information much easier than a plain text editor. Such editors may be suitable for programmers, but will unlikely become popular with less experienced authors.

Other editors, such as SoftQuad's XMetaL[XMetaL00], provide a structured editing environment. These editors read the XML document's DTD and constrain editing of the document to conform to the content models and attribute list definitions contained in the DTD. While XMetaL allows the editor interface to be customised via CSS stylesheets, there is still a need for toolkits and/or applications to allow editing interfaces to be built for vertical markets, such as the healthcare industry[Tkfam].

Figure 1. Tk_familypractice Screenshot

Because XML documents are structured, different views are possible of the data cotained within them. These views may be useful to authors for different purposes. For example, a typist may only wish to see the character data of a document. An editor may wish to see a condensed view of the element hierarchy, with some text for context. A stylesheet designer may wish to see only the tree view, with display of the context of deep element structures. In short, there are many different, possible ways to visualise an arbitrary XML document's content. Every editing application need not support all different possible views, but it is difficult for the software developer to anticipate which views and functionality will be required.

Swish[Swish00] is a general-purpose XML editor whose purpose is to provide easy document authoring. However, as noted above it is not straight-forward to provide a general-purpose tool that will satisfy all document authors. With this in mind, Swish has been engineered using a component-based approach and so is not just an XML editing application, but a toolkit for creating custom XML editors for vertical markets. The various modules which comprise Swish have been designed to be able to be used individually by software developers with a minimum of fuss.

In actual fact, Swish does not edit XML but rather manipulates a DOM tree. The fundamental component of Swish is a module that implements the DOM Level 2 specification, and handles DOM event generation and propagation. The DOM module relies on an XML parsing module in order to read XML files. Layered above these modules are two megawidgets to present graphical views of the document to the user: DOMText and TreeDOM. These megawidgets interact with the same in-memory DOM tree, and synchronise themselves using DOM events. Interacting with the user, while a major requirement for an editor, is not the only required functionality for the application. In addition, middleware functions are provided by a SOAP interface module, for interaction with other software agents.

Figure 2. Swish Architecture

Swish has been implemented using the Tcl/Tk[Tcl] scripting language and windowing toolkit. We feel that Tcl/Tk is an excellent choice for XML application development (and not just because we wrote the XML support packages for Tcl!). Tcl is a very high-level scripting language, and so it allows very rapid prototyping. This is important in order to be able to experiment with new editing paradigms and content visualisation ideas. It also also important for third-party developers to be able to quickly prototype application-specific editors for vertical markets. Tcl was the first major scripting language to have built-in support for Unicode/UTF-8, which is essential for XML applications. The Unicode support in Tk is exceptional - we have not had to write any additional code in order to display XML documents which include non-English characters. Another feature of Tcl is that it has clean, easy integration with other programming languages, especially Java. This is important for future work in integrating Java-based software into the editing environment, through the use of plugins.

TclXML

Parsing XML documents is, of course, an essential aspect of any XML application. TclXML is a Tcl package for parsing XML documents. It provides a callback mechanism, similar to SAX[SAX], to report document features to the application. The callback API for TclXML follows more usual Tcl conventions, rather than object-oriented API of SAX.

In order to receive callbacks for particular document constructs, the application configures an option corresponding to that feature in the parser object. The major configuration options are:

: -elementstartcommand [script]

: -elementendcommand [script]

: -characterdatacommand [script]

When the callback is invoked while parsing the document, data from the document is appended to the script as arguments and then callback is evaluated in the Tcl interpreter. A small example application to print out the character data of a document is as follows:

Example 1. Example TclXML Script

package require xml
proc CData {data} {
    puts $data
}
set parser [xml::parser]
$parser configure -characterdatacommand CData
$parser parse $xmldata
      

TclXML does not report to the application the syntax encountered in the XML document, but rather reports the XML Infoset[XMLInfo] of the document. That is, the markup is interpreted to find the data content of the document. For example, CDATA Sections are reported through the normal character data callback option and elements which use the special empty element syntax are reported as having a separate start and end tag. TclXML has options to report the low level syntax, in case an editor-type application is interested. However, most authors don't really care whether character data is encoded in a CDATA Section.

The implementation of TclXML employs a dual API, layered architecture, following the SAX model. The generic layer presents a Tcl API to the Tcl interpreter, providing a stable API for Tcl scripts, and a C API for a parser implementation. Drivers are available for a number of parser implementations, namely James Clark's expat and Apache's Xerces-C. There is also a parser class implemented in pure Tcl, for maximum portability and extensibility (but minimum performance).

This architecture makes it easy to switch between different parser classes, which each provide unique characteristics; Expat has higher performance, Xerces-C can validate a document against a DTD, and the Tcl parser can be modified on-the-fly. Using a high performance parser is certainly useful for certain classes of applications, but in practise it is of reduced usefulness for editor applications since much of the performance in reading an XML document is dominated by the construction of the DOM tree.

TclDOM

Many applications use a tree structure as their data model. XML documents are easily mapped to a tree structure, based on the element hierarchy. The Document Object Model (DOM)[DOM] is a standard interface for accessing, traversing and manipulating a tree representation of an XML document.

TclDOM is a Tcl language binding for the DOM, which implements most of DOM Level 1 and, at the time of writing, is a partial implementation of DOM Level 2. The TclDOM package provides additional required features, such as parsing and serialisation. Parsing is performed by calling the TclXML package to parse the document, and building the document tree from the parser callbacks. Serialisation of the DOM tree considers the data to be an expression of the document's Infoset, where syntax details are hidden by the implementation. For example, text nodes may be automatically converted to a CDATA Section if warranted by the number of special characters.

An important feature of TclDOM is the implementation of DOM Level 2 Events. Interfaces are provided to allow events to be generated, and for the application to register "listeners", or callbacks, for events. This allows different components of the system to be loosely-coupled, the DOM tree serves as an intra-process communication channel.

Figure 3. DOM Tree With Events

At present TclDOM is implemented as a pure-Tcl script. While this achieves a high degree of portability, performance is an issue. A C implementation is currently under development for improved performance.

Megawidgets

Tk is Tcl's windowing toolkit. A cross-platform toolkit, available on Unix/X, Apple Macintosh and Microsft Windows, it provides many basic GUI widgets, such as buttons, labels, entrys, and so on. A common programming technique when developing applications using Tk is to composite together a number of widgets into what is called a "megawidget". A megawidget presents an API to the Tcl script that makes it behave as if it were a built-in widget. Two megawidgets have been created for use in Swish: DOMText and TreeDOM.

The DOMText megawidget takes the Tk Text widget and makes it DOM aware. The Text widget is an input widget which provides functions for manipulating the text it contains in terms of characters and lines. A DOMText widget handles a DOM tree and displays the serialised XML text. The XML text is editable, but only character data and attribute values. Items in the Text widget are also selectable, but the selection applies to the DOM node which corresponds to the selection point.

Figure 4. A DOMText Megawidget

Editing the text in a DOMText megawidget updates the display and then updates the corresponding DOM text node. This action generates a DOMCharacterDataModified DOM event on the DOM node. Editing attribute values in the DOMText widget is not yet implemented. When a selection is made in the Text widget, a DOM click event is generated.

The DOMText megawidget registers event listeners (callbacks) for various DOM events, so that the megawidget will react to changes of state in the DOM tree. Changes in the structure of the element hierarchy will cause a DOMSubtreeModified event to occur. The top-most parent node of the changed structure is the subject of the event, and the text corresponding to this node, which will include all of its child nodes, is re-rendered. When click events are received the text corresponding to the DOM node is selected.

Configuration options are provided to control how the DOM tree is serialised and displayed in the Tk Text widget. The usual widget configuration options are included, such as background colour, font, border width, and so on, as well as widget-specific options, such as setting foreground colours for displaying various types of markup and character data. In order to support different visualisation paradigms, options are also provided to disable display of markup and to set the background colour of DOM nodes.

Figure 5. DOMText Modes

The TreeDOM megawidget takes the BWidget[BWidget] Tree widget and makes it DOM aware. The nodes in the DOM tree are mapped to nodes in the tree widget. Different icons are used to identify the various DOM node types. Text labels are displayed for each node: the name of a node, or a sample of the value of text nodes. Various aspects of the display of information for each node may be set with configuration options, including a feature to display part of the string value of an element node.

Figure 6. TreeDOM Megawidget

A Tree widget is an output-only widget, so the only DOM events the TreeDOM megawidget generates are click events when a node is selected.

The TreeDOM megawidget registers listeners (callbacks) for various DOM events, so that the megawidget will react to changes to the structure of the DOM tree. Changes in the structure of the element hierarchy will cause a DOMSubtreeModified event to occur. The top-most parent node of the changed structure is the subject of the event, and the Tree nodes corresponding to the altered DOM node are added or removed as necessary. Other DOM events are captured as well, for example to track changes in node names and values.

Figure 7. TreeDOM Events

Plugin Architecture

Swish is being developed as a platform for creating XML editing applications for vertical markets, and so it is essential to provide a mechanism for third-party developers to be able to extend the application with customised interfaces and features. A plugin module has been introduced to Swish for this purpose.

Plugins work in a straight-forward manner. Swish is configured to read files in a particular installation directory. Any files in that directory with the file extension ".tcl" are evaluated as Tcl scripts in the interpreter. The third-party developer supplies the Tcl script code to initialise their extension. Some plugins may be implemented in Tcl and consist of a large amount of Tcl code, but others may be written in other programming languages, such as Java, and only consist of a small amount of Tcl script code in order to pass control to the Java runtime environment.

The plugin module features an API to allow plugin scripts to interact with the main, or host, application. Facilities are provided to allow a plugin to add its own menu entrys, gain access to the DOM tree of the currently loaded document, and so on.

One problem with implementing a plugin system is that plugins may conflict with each other. Tcl provides mechanisms for ensuring that the Tcl script code of each plugin can be isolated, but they also need to have their configuration data separated too. Accessing and storing their own configuration data is a critical aspect of the operation of most plugins. There are additional problems when plugins are enabled or disabled; the configuration data for a disabled plugin may not be handled properly. A simple approach that overcomes these problems is to store the configuration for the system (including Swish itself) as an XML document.

XML is quite capable of representing arbitrarily complex data structures used by software systems. In the Swish plugin system, each plugin registers a name and that name is used as the element name for the plugin's configuration data. At application startup time, the configuration document is parsed into a DOM tree. When the plugin registers itself with the plugin system, it is passed the DOM node corresponding to its configuration. The plugin may then read the DOM subtree to obtain its own configuration data. If the plugin wishes to change its configuration, it simply modifies its DOM subtree. The plugin system will subsequently receive a DOM DOMSubtreeModified event and can react by automatically saving the configuration document.

Figure 8. XML Configuration Document

<Preferences>
  <Category name="Input">
    <Parser type="expat">
    <Directory>/home/test/XML-Docs</Directory>
  </Category>
  <Category name="Office 2000 Compatibility">
    <MSWord9 state="normal"/>
  </Category>
  <Category name="Display"/>
</Preferences>

In the case where a plugin is disabled, the XML element corresponding to that plugin can be safely ignored. The only issue here is that when a large number of plugins have been removed the configuration document may grow too large. It is planned to implement an improved tool for managing plugins and configuration data to alleviate this potential problem.

An example plugin that ships with Swish is able to allow Microsoft Word 9 (Microsoft Office 2000) to be read as XML documents. The "Save As A Web Page" feature of MS Word 9 causes the currently loaded document to be saved in a format that is close to, but not quite, XML. In fact, Word uses "XML Data Islands" in HTML to store formatting information. Unfortunately, these files are not well-formed XML and so on cannot be used directly by XML processors. The MSWord9 plugin modifies the Tcl-only parser class of TclXML so that these documents can be read. The parser's normal checks for well-formedness are relaxed sufficiently so that the HTML syntax found in "Web Page" documents do not cause errors. We have found this useful in converting MS Word documents to XML, by first saving as a "Web Page", manually correcting some structures in Swish, saving the file as proper XML and then transforming the XML document using XSL.

Figure 9. A Microsoft Word Document In Swish

TclSOAP - "Home And Away"

In today's modern world of computing, no application stands alone. Interoperability of applications allows users to leverage the capabilities of individual programs. There are a number of middleware standards for achieving this goal, such as COM or CORBA. The Simple Object Access protocol (SOAP)[SOAP] is a recently introduced middleware standard which utilises HTTP and XML for performing remote procedure calls.

A Tcl package has been implemented to allow Swish to be both a SOAP client and server, TclSOAP. The initial version "number" is Home And Away, which will soon be followed by Days Of Our Lives. TclSOAP uses the TclDOM package to read and write SOAP format messages. Tcl provides a HTTP client package, which is used to send SOAP messages, and it is planned to use the Tcl Web Server, a complete web server written entirely as a Tcl script, for receiving SOAP calls.

It is planned to SOAP-enable virtually every aspect of Swish's functionality. This will allow external applications, even remotely distributed, to fully script Swish's behaviour.

Conclusion

Zveno's Swish is an Open Source, cross-platform GUI XML editor written using the Tcl/Tk scripting language and windowing toolkit. It is known to run on Solaris, Linux, Macintosh and Windows environments, and should be able to operate on any computer to which Tcl/Tk has been ported. Two major goals of Swish are to allow experimentation and implementation of innovative and novel content visualisation paradigms, and to support development of editing interfaces for vertical markets.

Swish takes a component-based approach to software development. The major modules of the editor application are developed as fully functional, independant packages. These include an XML parsing package, DOM implementation, SOAP client/server package and DOM-based megawidgets. Application developers can, and indeed are, taking these individual packages and using them as an XML toolkit for third-party applications.

XML is not only the subject of Swish's functions, it is also used by Swish for managing configuration data. The use of XML for storing and accessing application configuration data is a very useful approach in general for all types of software, and indeed current industry practise bears witness to this.

References

[XMLSpy00] Icon Information-Systems. http://www.xmlspy.com/ . 2000.

[XMetaL00] SoftQuad. http://www.softquad.com/ . 2000.

[Swish00] Zveno. http://www.zveno.com/ . 2000.

[Tcl] John K. Ousterhout. http://dev.ajubasolutions.com/ . 2000.

[SAX] D. Megginson, et al.. http://www.megginson.com/ . 2000.

[XMLInfo] J. Cowan. http://www.w3.org/TR/ . 2000.

[DOM] L. Wood, et al.. http://www.w3.org/DOM/ . 2000.

[BWidget] Unifix. http://www.unifix-online.com/BWidget/ . 2000.

[SOAP] D. Box, et al.. http://www.w3.org/TR/SOAP/ . 2000.