Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

UML, XMI, and code generation, Part 3

Use stereotypes and tags to store information in the model

Return to article.


Listing 2. The updated stylesheet
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xi="http://ananas.org/2002/xi/rules"
                xmlns:UML="org.omg/UML/1.4"
                exclude-result-prefixes="UML"
                version="1.0"
                xmlns:xalan="http://xml.apache.org/xslt">

<xsl:output xi:suffix="xsd" indent="yes" xalan:indent-amount="2"/>

<xsl:variable name="root-id" select="/XMI/XMI.content/UML:Model/UML:Namespace.ownedElement/UML:Stereotype[@name='root']/@xmi.id"/>
<xsl:variable name="position-id" select="/XMI/XMI.content/UML:Model/UML:Namespace.ownedElement/UML:TagDefinition[@name='position']/@xmi.id"/>

<xsl:template match="XMI[@xmi.version='1.2']">
   <xsl:apply-templates select="XMI.content/UML:Model"/>
</xsl:template>

<xsl:template match="XMI">
   <xsl:message terminate="yes">Unknown XMI version</xsl:message>
</xsl:template>

<xsl:template match="UML:Model">
   <xs:schema targetNamespace="http://psol.com/uml/{@name}">
      <xsl:apply-templates select="UML:Namespace.ownedElement/UML:Class[UML:ModelElement.stereotype/UML:Stereotype/@xmi.idref=$root-id]"/>
   </xs:schema>
</xsl:template>

<xsl:template match="UML:Class">
   <xsl:param name="multiplicity"/>
   <xsl:variable name="id" select="@xmi.id"/>
   <xs:element name="{@name}">
      <!-- test because the processor reports an error if the parameter was not set
           (i.e. for root elements, the parameter is never set)                     -->
      <xsl:if test="$multiplicity">
         <xsl:apply-templates select="$multiplicity"/>
      </xsl:if>
      <xs:complexType>
         <xs:sequence>
            <xsl:apply-templates/>
            <xsl:apply-templates select="//UML:Association[UML:Association.connection/UML:AssociationEnd[1]/UML:AssociationEnd.participant/UML:Class[@xmi.idref=$id]]"
                                 mode="association">
               <xsl:sort select="UML:ModelElement.taggedValue/UML:TaggedValue[UML:TaggedValue.type/UML:TagDefinition[@xmi.idref=$position-id]]/@dataValue"
                         data-type="number"/>
            </xsl:apply-templates>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
</xsl:template>

<xsl:template match="UML:Association" mode="association">
   <xsl:variable name="id" select="UML:Association.connection/UML:AssociationEnd[2]/UML:AssociationEnd.participant/UML:Class/@xmi.idref"/>
   <xsl:apply-templates select="//UML:Class[@xmi.id=$id]" mode="association">
      <xsl:with-param name="multiplicity" select=".//UML:MultiplicityRange"/>
   </xsl:apply-templates>
</xsl:template>

<xsl:template match="UML:Class[UML:ModelElement.stereotype/UML:Stereotype/@xmi.idref=$root-id]" mode="association">
   <xsl:param name="multiplicity"/>
   <xs:element ref="{@name}">
      <xsl:apply-templates select="$multiplicity"/>
   </xs:element>
</xsl:template>

<xsl:template match="UML:Class" mode="association">
   <xsl:param name="multiplicity"/>
   <xsl:apply-templates select=".">
      <xsl:with-param name="multiplicity" select="$multiplicity"/>
   </xsl:apply-templates>
</xsl:template>

<xsl:template match="UML:Attribute">
   <xs:element name="{@name}" type="xs:string">
      <xsl:apply-templates select=".//UML:MultiplicityRange"/>
   </xs:element>
</xsl:template>

<xsl:template match="UML:MultiplicityRange">
   <xsl:if test="@lower and number(@lower) != 1">
      <xsl:attribute name="minOccurs"><xsl:value-of select="@lower"/></xsl:attribute>
   </xsl:if>
   <xsl:choose>
      <xsl:when test="@upper and number(@upper) = -1">
         <xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
      </xsl:when>
      <xsl:when test="@upper and number(@upper) != 1">
         <xsl:attribute name="maxOccurs"><xsl:value-of select="@upper"/></xsl:attribute>
      </xsl:when>
   </xsl:choose>
</xsl:template>

<xsl:template match="text()">
   <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

</xsl:stylesheet>

Return to article.