Home Books Software Projects

Transforming XMI to HTML
Part Two

In Part One of this project we introduced the process of transforming XMI to HTML. In this continuation we will see how the transformation of the class details is performed and conclude with an overview of the tools used for the project.

Specification

Next we will take a look at how the specification for a class is generated. The specification identifies an interface which the class implements. We want a hyperlink to be created so that we may navigate to the definition of the interface.




<xsl:template match="specification">

    <xsl:variable name="target">

    <xsl:value-of select='XMI.reference/@target'/>

    </xsl:variable>



    <xsl:variable name="interface">

    <xsl:value-of

        select='//Interface[@XMI.id=normalize($target)]/name'/>   

    </xsl:variable>



    <tr>

        <td width="20%"

            class="info-title">Specification:</td>        



        <td colspan="2" class="info">

        <a href="#{$interface}">

        <xsl:value-of select='$interface'/>

        </a>

        </td>

    </tr>

</xsl:template>




To generate the specification name we have to find the interface which the class implements. This gets complicated because XMI uses id's to identify elements in the model. To get the interface name we again utilize XSL variables so that variable substitution may be used when generating the hyperlink for the specification.

In this case we use two variables, target and interface, to keep the code clean. The target variable gets the XMI id for the interface. The interface variable uses the XMI id to locate the interface within the XMI document and retrieve its name. Finally, the hyperlink is generated by using the interface variable.

Generalization

Finding the superclasses for a class is a little bit more tricky than finding the interfaces. This is so because the superclass relationship is stored in the Generalization model element, not the class, whereas the interface is identified as a specification on the class, as we just saw. Keep in mind that an interface is also a generalizable element and as such, may have another interface as a supertype.




<xsl:template match="Generalization">

    <xsl:variable name="supertype">

    <xsl:value-of select='supertype/XMI.reference/@target'/>

    </xsl:variable>



    <xsl:variable name="classifier">

    <xsl:value-of select="//*

        [qname()='Class' or qname()='Interface']

        [@XMI.id=normalize($supertype)]/name"/>

    </xsl:variable>

	

    <tr>

    <td width="20%" class="info-title">Supertype:</td>

    <td colspan="2" class="info">

        <a href="#{$classifier}">

        <xsl:value-of select='$classifier'/>

        </a>

        </td>

    </tr>

</xsl:template>




This template matches all Generalization model elements but as the reader may recall, the select clause on the apply-templates directive is looking for matches where the subtype reference equals the reference for the class whose ancestors we are looking for. Once we find such a generalization, we get the reference for the supertype into a variable. Then we create another variable which finds the name for the supertype. Finally we generate the HTML to identify the supertype and add a hyperlink for navigation to the supertype definition.

Notice the use of the XSL qname() method when finding the name for the supertype. We are looking for either a class or an interface because, as we said earlier, either can have an ancestor. What isn't shown is that this template is also used during generation of the HTML for interfaces as well. What is nice is that this template is usable for both classes and interfaces with this slight addition. Also for this reason we leave the title as Supertype since it applies to both.

Attributes and Operations

Since the template for generating HTML for attributes is similar to that for operations, let's look at operations first, which are more complex.




<xsl:template match="feature/Operation">

    <xsl:variable name="target">

    <xsl:apply-templates

         select="parameter/Parameter/kind[@XMI.value='return']"         

         mode="get-name" />

    </xsl:variable>



    <xsl:variable name="classifier">

    <xsl:value-of select="//*

        [qname()='Class' or qname()='DataType']

        [@XMI.id=normalize($target)]/name"/>

    </xsl:variable>



    <tr>

        <td class="feature-detail">

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

        </td>

        <td class="feature-detail">

        <a href="#{$classifier}">

        <xsl:value-of select='$classifier'/>

        </a>

        </td>

        <td class="feature-detail">

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

        </td>

    </tr>

	



Since operations have a return value, we first set up two XSL variables which are used to get the name of the return type, target and classifier. The return parameter is found in the list of parameters for an operation, which may also include input parameters. Fortunately, XMI provides a parameter kind designator. We look for a kind equal to 'return' and then get the type of the return parameter.

The generation of the HTML for an operation starts by generating the code for the visibility, return type and name of the operation, and includes a hyperlink to the definition for the return type.

If an operation is specified with any input parameters, these are created next by the template.




    <xsl:variable name="parameter-count">

    <xsl:value-of

        select="count(parameter/Parameter/kind[@XMI.value='in'])"/>  

    </xsl:variable>

	

    <xsl:if test="not(normalize($parameter-count)='0')">

	

    <tr>

        <td class="feature-detail" > </td>

        <td class="parameter-heading"

            valign="top">Parameters:</td>

        <td bgcolor="#ffffff" align="right">

        <table width="85%" align="right" 

            cellpadding="0" cellspacing="0" border="0">

            <xsl:apply-templates

                select="parameter/Parameter/kind[@XMI.value='in']" />

        </table>

        </td>

    </tr>

	

    </xsl:if >

	

</xsl:template>





Since we don't want to ouput any HTML if the operation has no input parameters, we first want to count the number of input parameters. XSL provides the function count() for this purpose. Also for the first time you see the use of the XSL if directive, which allows us to implement some basic boolean logic. If the count is not zero, then output the HTML.

As you can see, the list of input parameters is actually contained in its own table in the output. This allows the input parameters to appear nicely formated in columns for the type and name of each parameter. To retrieve this list, another XSL template is applied. The template may be found in the full source code for the project.

Finally, completing the output for the definition of a class, here is the template for the attributes. The HTML generated for each attribute includes the visibility, type and name for the attribute, and includes a hyperlink to the definition for the attribute type.




<xsl:template match="feature/Attribute">

    <xsl:variable name="target">

    <xsl:value-of select='type/XMI.reference/@target'/>

    </xsl:variable>

	

    <xsl:variable name="classifier">

    <xsl:value-of select="//*

        [qname()='Class' or qname()='DataType']

        [@XMI.id=normalize($target)]/name"/>

    </xsl:variable>



    <tr>

        <td class="feature-detail">

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

        </td>

		

        <td class="feature-detail">

        <a href="#{$classifier}">

        <xsl:value-of select='$classifier'/>

        </a>

        </td>

		

        <td class="feature-detail">

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

        </td>

    </tr>

</xsl:template>





That concludes our walk-through of the XSL rules for the XMI to HTML transformation of classes. Other transformation rules included in the full source code include the rules for generating HTML for interfaces, which are substantially similar to the rules for classes, and in fact reuse a good portion of the same rules.

To conclude this project, let's take a quick look at the tools that were used. Keep in mind that this is experimental technology. Everything presented so far is still evolving.

XSLT

The key technology we have employed in this project is XSLT, which is the portion of the emerging XSL standard which provides a language for transforming XML documents into other types of documents. XSLT is currently a W3C Version 1.0 Recommendation (November 16, 1999) and may be found at the W3C site. The principal editor of this document is James Clark, a pioneer in the XML field.

Xalan, Apache XML Project

The tool which was used to run the XSLT style sheet is the excellent Xalan-Java XSLT transformation engine. This software was implemented by Scott Boag and other developers at Lotus and IBM has been donated to the open-source Apache XML project, where it is now supported. We found the software to be highly reliable and relatively bug free. You may follow this project by subscribing to the xalan-dev@xml.apache.org mailing list or reading the archived messages.

ArgoUML

The UML diagram and XMI for this project was produced by ArgoUML, described as a 'Free Object-Oriented Design Tool with Cognitive Support'. Also open-source and written in Java, ArgoUML is the creation of University of California graduate student Jason Robbins and a group of open-sourcers who participate in the project. While still in pre-version 1.0 status, ArgoUML already provides a wide range of functionality. It has supported XMI from the beginning as the principal file representation for a UML model under development.

A unique set of functionality that this tool provides is what Jason Robbins calls 'cognitive support'. This is the capability of the tool to monitor an object-oriented design while it is under development in order to actively provide suggestions for improving the design.

Anybody interested in participating in this project can visit the ArgoUML site or the active discussion group for the project.

Source Code

The complete XSL source code for this project as well as the XMI file is provided as a download. Remember, this is experimental software, still under development.

The software follows the open-source model and is protected by the GNU General Public License (GPL). Please read the license agreement in full prior to downloading. By downloading you agree to the terms of the GPL.

Download the XMI to HTML project sources.

To Be Continued...

This concludes our project for now. We hope the information presented was informative and we welcome suggestions for improvements. Until a message board is established, please send email. And keep posted for new developments...

Links: