Skip to main content

skip to main content

developerWorks  >  Sample IT projects  >

Using XML and XSL for code generation

XSL stylesheets enable powerful and flexible generation of pervasive applications

developerWorks
Document options

Document options requiring JavaScript are not displayed


Learn and share!

Exchange know-how with your peers -- try our new Pass It Along beta app


Rate this page

Help us improve this content


Level: Introductory

Barry Beggs (beggs@us.ibm.com), Pervasive Solution Developer, IBM
Joan Boone (jpboone@us.ibm.com), Senior Software Engineer, IBM

01 May 2001

This article describes an atypical use of XSL stylesheets to create applications for pervasive devices by transforming an XML document to source code. The techniques and samples described here were used to implement an application builder tool that generates DB2 Everyplace applications for Palm and EPOC devices.

The big picture

The application builder tool uses XML to define components of the tool user interface and to define the user interface and behavior of the generated application. XML serves this purpose well because it provides an efficient way to structure information about applications that are not highly complex. Pervasive devices usually have a fairly small form factor, which reduces an application's complexity in terms of user interface design and business logic. The XML document produced by the tool is called a project file and is input to the XSLT processor along with several stylesheets. The stylesheets are applied to the project file to generate C source code, and header, resource, and makefiles for a Palm application. The figure below illustrates how the tool uses XML documents and XSL stylesheets.


Using XML and XSL stylesheets
Using XML and XSL stylesheets


Back to top


Defining the tool user interface with XML

The application builder for IBM DB2 Everyplace is a drag-and-drop tool that defines its widget set in XML. Defining the widgets in XML enables customization by the application developer and easy extensions when other platforms and user interfaces are added. The tool loads the XML file during initialization and creates the widget palette based on the XML definitions. A PalmOS Button sample is shown in Listing 1.

XML is used to define the name of the button, actions when selected, and properties of the button. The PalmOS PilRC toolset definition is used for the attributes of the widgets, which can be dragged from the palette and dropped on a form as needed.



Back to top


Defining the generated application user interface and business logic with XML

The application builder also uses XML to store information about the current project. A sample with a database table, one form, and a label on the form is shown in Listing 2.

The project XML document includes definitions for information like the current location, definition of database tables, platform type and details, forms and widgets, and SQL statements. The XSL Stylesheets transform this project XML to a form that can be used to generate target-specific code.



Back to top


Structuring stylesheets for extensibility

One of the objectives in designing this tool was to enable application generation for multiple target devices in multiple programming languages. For example, the tool generates C applications for Palm and EPOC devices, and is architected to simplify support for other databases or programming languages. The structure of the stylesheets not only lends itself to platform and language extensibility, but also has the added benefit of easing reuse and maintainability of many stylesheets. Here are some of the organizational techniques used:

  • XSL for platform-specific code generation is contained in separate stylesheets. For example, individual stylesheets are defined for each Palm user interface resource, such as a form, field, list, or button. Each resource stylesheet contains all of the logic needed to define and manage a resource using the Palm API, such as initializing, setting, and retrieving the contents of a field, or drawing a list.
  • XSL for generation of functions that are identical across platforms for a given language are contained in separate stylesheets. For instance, common database functions such as connecting/disconnecting from a database and executing SQL are grouped together in the same stylesheets. Common application functions such as error handling and logging can also be grouped together.

The tool generates code for applications that use a relational database. The XSL for SQL generation is contained in separate stylesheets and can be used across multiple platforms and programming languages. The figure below illustrates the file organization for the stylesheets.


File organization for stylesheets
File organization for stylesheets


Back to top


Generating code

The XSL stylesheets are run against the project XML to create "C" code and supporting files which will be built by the native PalmOS GNU tools. The following XSL sample handles generation of forms (it is extracted from the PersonList sample project that is available with the application builder tool):

<?xml version="1.0" ?>
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0">
  <xsl:output method="text" />
  <xsl:strip-space elements="*" />
  <!--  Process all the forms   -->
- <xsl:template match="Forms"> #find all forms elements
  <xsl:apply-templates select="Form" mode="DrawForm" /> #create code to draw the form
 <xsl:apply-templates select="Form" mode="ClearForm" /> #create code to clear form
  <xsl:apply-templates select="Form" mode="HandleEvent" />
  #here is the main palm event handler
  <xsl:text>static Boolean ApplicationHandleEvent(EventPtrevent) 
     { FormPtr frm; Int formId; Boolean handled = false;</xsl:text> 
- <![CDATA[           #need cdata because of > in code
   if (event->eType == frmLoadEvent)
   {
      formId = event->data.frmLoad.formID;
      frm = FrmInitForm(formId);
      FrmSetActiveForm(frm);
      switch (formId)
      {
  ]]>  <xsl:apply-templates select="Form" mode="SetEventHandler"/>
  <xsl:text>otherwise: break; } handled = true; } return handled;}</xsl:text>
  </xsl:stylesheet>
The following is a section of the "c" code output generated by processing
the project XML in the business logic section of this paper with the above
XSL sample:
/****************************************************************************/
// Draw form
/****************************************************************************/
static void Person_DrawForm()
 {
  FormPtr form = FrmGetActiveForm();
  ListPtr list;
  FrmDrawForm(form);
  }
static void ClearPerson_()
 {
  FormPtr form = FrmGetActiveForm();
  FrmDrawForm(form);
  }
/******************************************************************************/
//  Event handlers for each form
/******************************************************************************/
static Boolean Person_HandleEvent(EventPtr event)
{
  Boolean handled;
  int i;
  RectangleType theBounds;
  SWord         x, y;
  Boolean       penDown;
  RectangleType sigBounds;
  handled = false;
  switch (event->eType)
  {
     case ctlSelectEvent:
        switch (event->data.ctlEnter.controlID)
        {
        }
        break;
     case frmOpenEvent:
        SelectFrom_Table1(Table1_RowBuffer.currentSelect,true);
        FillIn_Person_Buffer();
        Person_DrawForm();
        handled = true;
        break;
     case menuEvent:
        switch (event->data.ctlEnter.controlID)
        {
        }
        handled = true;
        break;
  }
  return(handled);
}
static Boolean ApplicationHandleEvent(EventPtr event)
{
  FormPtr frm;
  Int formId;
  Boolean handled = false;
  if (event->eType == frmLoadEvent)
  {
     formId = event->data.frmLoad.formID;
     frm = FrmInitForm(formId);
     FrmSetActiveForm(frm);
     switch (formId)
     {
        case Person_:
           FrmSetEventHandler(frm, Person_HandleEvent);
           break;
        otherwise:
           break;
     }
     handled = true;
  }
  return handled;
}

Files created in the code generation process are .c, .h., .rcp (GNU resource file), and a makefile. The native Palm application (.prc) is then generated using the Palm GNU toolset.



Back to top


XSL stylesheet techniques

Using XSL stylesheets to generate code presents some challenges that are not encountered when using stylesheets in a more traditional manner. Transforms from one XML document to another may only require a single pass when the underlying structure of the input and output documents is similar. When generating source code from an XML document, there may be very little similarity between input and output document structures, thus requiring multiple passes though the XML project file to produce the code. For example, when generating code for a form in a Palm application, each Form element must be processed multiple times to produce C code to define data buffers, event handler and initialization functions.



Back to top


Global variables

Global variables provide an easy way to establish reference points to elements in the project file that are processed multiple times. The variables defined below are used to reference the Project, Tables, and Forms nodes, respectively.

<xsl:variable name="ProjectNode" select="/Project"></xsl:variable>
<xsl:variable name="TablesNode" select="/Project/Tables"></xsl:variable>
<xsl:variable name="FormsNode" select="/Project/Application/Forms"></xsl:variable>

The following XSL example illustrates how the Tables node is used. This named template is called with a Table name parameter, which is used to search though each Table node to produce a generic table name, such as Table2, derived from the Table element's position under the Table node.

<xsl:template name="tablePosition">
    <xsl:param name="tblprm" >tablename</xsl:param>
    <xsl:for-each select="$TablesNode/Table">
       <xsl:variable name="tblName"><xsl:value-of select="@name"/></xsl:variable>
       <xsl:if test="string($tblName)=string($tblprm)">
         <xsl:value-of select="position()"/>
       </xsl:if>
   </xsl:for-each>
</xsl:template>



Back to top


Reusable templates

The above example also illustrates the use of templates for common, reusable functions. XSLT named templates provide a convenient way to encapsulate common functions that can be called repeatedly. Another example is illustrated below, where a lookup of the SQL data type is performed by passing the corresponding table and column names as parameters. The template generates values like SQL_INTEGER, SQL_CHAR, and SQL_DATE that are used as parameters in SQLBindParameters calls in the generated code. The translated function in this template converts the data type string to uppercase.

<xsl:template name="sqlDatatype">
   <xsl:param name="tbl">tableName</xsl:param>
   <xsl:param name="col">columnName</xsl:param>
   <xsl:variable name="dataType">
      <xsl:value-of select="//Table[@name=$tbl]/Column[@name=$col]/@DataType"/>
   </xsl:variable>
   <xsl:variable name="ucDataType">
     <xsl:value-of select='translate($dataType, "Abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ")'/>
   </xsl:variable>
   <xsl:text>SQL_</xsl:text>
   <xsl:if test="$ucDataType='DATE' or $ucDataType='TIME'">
      <xsl:text>TYPE_</xsl:text>
   </xsl:if>
   <xsl:value-of select="$ucDataType"/>
   <xsl:if test="$ucDataType='INT'">
      <xsl:text>EGER</xsl:text>
    </xsl:if>
</xsl:template>



Back to top


Summary

XSL stylesheets are not generally used to perform transforms where the input and output are as structurally dissimilar as the application project file and C source code. However, we have found them to be very effective for generating pervasive applications that are not as complex as their enterprise counterparts. The user interfaces are simpler as far as number of forms and widget types, and similarly the business logic is not as complex. Hence, the structure of an application is fairly formulaic, a characteristic that lends itself well to a stylesheet implementation.



Resources



About the authors

Barry Beggs has created palmtop applications as principal partner for GolfTech Products. Barry has also worked on various Telephony and IP projects, most recently working with IP QoS and VoIP H.323 signalling. Current projects are the WebSphere Everyplace Suite SDK, Unified Communication, investigation of databases for WAP clients, and Wireless SIP. Barry can be reached at beggs@us.ibm.com.


Joan Boone is a senior software engineer at IBM Research Triangle Park, NC. She is currently working on enterprise mobility solutions.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top