Skip to main content

skip to main content

developerWorks  >  XML  >

UML, XMI, and code generation, Part 3

Use stereotypes and tags to store information in the model

developerWorks

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.